How to get a list with the Typesafe config library - scala

I'm trying in Scala to get a list from a config file like something.conf with TypeSafe.
In something.conf I set the parameter:
mylist=["AA","BB"]
and in my Scala code I do:
val myList = modifyConfig.getStringList("mylist")
Simple configuration parameters works fine but could somebody give me an example of how to extract a list?

As #ghik notes, the Typesafe Config library is Java based, so you get a java.util.List[String] instead of a scala.List[String]. So either you make a conversion to a scala.List:
import collection.JavaConversions._
val myList = modifyConfig.getStringList("mylist").toList
Or (probably less awkward) you look for a Scala library. The tools wiki links at least to these maintained libraries:
Configrity
Bee Config
(Disclaimer: I don't use these, so you will have to check that they support your types and format)

For the record, since Scala 2.12 JavaConversions are deprecated so you can:
import collection.JavaConverters._
val myList: List[String] = modifyConfig.getStringList("mylist").asScala.toList

You can try my scala wrapper https://github.com/andr83/scalaconfig - it supports reading native scala types directly from config object. In your case it will look:
val myList = modifyConfig.as[List[String]]("mylist")

Starting Scala 2.13, the standard library provides Java to Scala implicit list conversions via scala.jdk.CollectionConverters:
import scala.jdk.CollectionConverters._
val myList: List[String] = conf.getStringList("mylist").asScala.toList
This replaces deprecated packages scala.collection.JavaConverters/JavaConversions.

Related

convert play getIntList to scala List[Int] simply

I have a Play app where I'd like to read a list of integers. The Configuration object returns Option[java.util.List[java.lang.Integer]] but I'd like to return the scala type Option[List[Int]].
I have used JavaConversions to return the scala List mylist.map(_.toList).
But I'm unsure about converting the underlying element type from java.lang.Integer to Int in a neat way and without using any additional libraries.
Any ideas?
Just map the list:
import scala.collection.JavaConverters._
mylist.map(_.asScala.toList.map(_.intValue))
(it's generally recommended to prefer JavaConverters, which add toJava and toScala methods, to JavaConversions).

Storing an object to a file

I want to save an object (an instance of a class) to a file. I didn't find any valuable example of it. Do I need to use serialization for it?
How do I do that?
UPDATE:
Here is how I tried to do that
import scala.util.Marshal
import scala.io.Source
import scala.collection.immutable
import java.io._
object Example {
class Foo(val message: String) extends scala.Serializable
val foo = new Foo("qweqwe")
val out = new FileOutputStream("out123.txt")
out.write(Marshal.dump(foo))
out.close
}
First of all, out123.txt contains many extra data and it was in a wrong encoding. My gut tells me there should be another proper way.
On the last ScalaDays Heather introduced a new library which gives a new cool mechanism for serialization - pickling. I think it's would be an idiomatic way in scala to use serialization and just what you want.
Check out a paper on this topic, slides and talk on ScalaDays'13
It is also possible to serialize to and deserialize from JSON using Jackson.
A nice wrapper that makes it Scala friendly is Jacks
JSON has the following advantages
a simple human readable text
a rather efficient format byte wise
it can be used directly by Javascript
and even be natively stored and queried using a DB like Mongo DB
(Edit) Example Usage
Serializing to JSON:
val json = JacksMapper.writeValueAsString[MyClass](instance)
... and deserializing
val obj = JacksMapper.readValue[MyClass](json)
Take a look at Twitter Chill to handle your serialization: https://github.com/twitter/chill. It's a Scala helper for the Kyro serialization library. The documentation/example on the Github page looks to be sufficient for your needs.
Just add my answer here for the convenience of someone like me.
The pickling library, which is mentioned by #4lex1v, only supports Scala 2.10/2.11 but I'm using Scala 2.12. So I'm not able to use it in my project.
And then I find out BooPickle. It supports Scala 2.11 as well as 2.12!
Here's the example:
import boopickle.Default._
val data = Seq("Hello", "World!")
val buf = Pickle.intoBytes(data)
val helloWorld = Unpickle[Seq[String]].fromBytes(buf)
More details please check here.

how to read properties file in scala

I am new to Scala programming and I wanted to read a properties file in Scala.
I can't find any APIs to read a property file in Scala.
Please let me know if there are any API for this or other way to read properties files in Scala.
Beside form Java API, there is a library by Typesafe called config with a good API for working with configuration files of different types.
You will have to do it in similar way you would with with Scala Map to java.util.Map. java.util.Properties extends java.util.HashTable whiche extends java.util.Dictionary.
scala.collection.JavaConverters has functions to convert to and fro from Dictionary to Scala mutable.Map:
val x = new Properties
//load from .properties file here.
import scala.collection.JavaConverters._
scala> x.asScala
res4: scala.collection.mutable.Map[String,String] = Map()
You can then use Map above. To get and retrieve. But if you wish to convert it back to Properties type (to store back etc), you might have to type cast it manually then.
You can just use the Java API.
Consider something along the lines
def getPropertyX: Option[String] = Source.fromFile(fileName)
.getLines()
.find(_.startsWith("propertyX="))
.map(_.replace("propertyX=", ""))

How to retrieve Scala's version in REPL? [duplicate]

This question already has answers here:
How do I get the Scala version from within Scala itself?
(4 answers)
Closed 1 year ago.
When trying to run some code in online interpreters or with IRC bots, I always wonder which version of Scala they support.
Is there a way to retrieve the version of Scala from within the interpreter?
For Scala 2, use scala.util.Properties.versionNumberString (or versionString):
scala> scala.util.Properties.versionString
val res0: String = version 2.13.6
scala> scala.util.Properties.versionNumberString
val res1: String = 2.13.6
For Scala 3, if you do the same thing, you may be surprised by the answer:
% scala3 -version
Scala code runner version 3.0.1 -- Copyright 2002-2021, LAMP/EPFL
% scala3
scala> scala.util.Properties.versionNumberString
val res0: String = 2.13.6
That's because Scala 3.0.x uses the Scala 2 standard library as-is, to aid migration, and makes only a small number of additions. (Eventually the standard libraries will no longer remain synchronized like this.)
Here's how to get the Scala 3 compiler version:
scala> dotty.tools.dotc.config.Properties.simpleVersionString
val res0: String = 3.0.1
This only works if the scala3-compiler JAR is on your classpath. (In the standard Scala 3 REPL, it is; in some other environments, it might not be.)
If the compiler isn't on your classpath and you want the full Scala 3 version string, see Dmitrii's answer.
If the compiler isn't on your classpath but you just want to find out at runtime whether you're on Scala 2 or 3, well... perhaps there's a cleaner/better way, you tell me, but one way that works is:
util.Try(Class.forName("scala.CanEqual")).isSuccess
Here, the choice of scala.CanEqual is arbitrary, it could be any of the small number of classes that are in scala3-library but not scala-library.
But if you are tempted to go that route, you might instead consider including version-specific source in your project, or passing the Scala version via sbt-buildinfo.
scala> scala.util.Properties.versionMsg
res: String = Scala library version 2.9.0.1 -- Copyright 2002-2011, LAMP/EPFL
Looks of course like the library version and not like the language version, but I think currently there won’t be a real difference in practice.
If you need just the version number without the "version" keyword you can use versionNumberString function.
scala> scala.util.Properties.versionNumberString
res1: String = 2.12.3
If you want to get the exact Scala 3 version, you can read it from the Manifest file
.../scala3-library_3-3.0.1.jar!/META-INF/MANIFEST.MF
import java.io.FileInputStream
import java.util.jar.JarInputStream
val scala3LibJar = classOf[CanEqual[_, _]].getProtectionDomain.getCodeSource.getLocation.toURI.getPath
val manifest = new JarInputStream(new FileInputStream(scala3LibJar)).getManifest
manifest.getMainAttributes.getValue("Implementation-Version")
Example in Scastie:

Convert Scala Set into Java (java.util.Set)?

I have a Set in Scala (I can choose any implementation as I am creating the Set. The Java library I am using is expecting a java.util.Set[String].
Is the following the correct way to do this in Scala (using scala.collection.jcl.HashSet#underlying):
import com.javalibrary.Animals
var classes = new scala.collection.jcl.HashSet[String]
classes += "Amphibian"
classes += "Reptile"
Animals.find(classes.underlying)
It seems to be working, but since I am very new to Scala I want to know if this is the preferred way (any other way I try I am getting a type-mismatch error):
error: type mismatch;
found : scala.collection.jcl.HashSet[String]
required: java.util.Set[_]
If you were asking about Scala 2.8, Java collections interoperability is supplied by scala.collection.JavaConversions. In this case, you want JavaConversions.asSet(...) (there's one for each direction, Java -> Scala and Scala -> Java).
For Scala 2.7, each scala.collection.jcl class that wraps a Java collection has an underlying property which provides the wrapped Java collection instance.
Since Scala 2.12.0 scala.collection.JavaConversions is deprecated:
Therefore, this API has been deprecated and JavaConverters should be used instead. JavaConverters provides the same conversions, but through extension methods.
And since Scala 2.8.1 you can use scala.collection.JavaConverters for this purpose:
import scala.collection.JavaConverters._
val javaSet = new java.util.HashSet[String]()
val scalaSet = javaSet.asScala
val javaSetAgain = scalaSet.asJava
For 2.7.x I highly recommend using: http://github.com/jorgeortiz85/scala-javautils
Note that starting Scala 2.13, package scala.jdk.CollectionConverters replaces deprecated packages scala.collection.JavaConverters/JavaConversions._:
import scala.jdk.CollectionConverters._
// val scalaSet: Set[String] = Set("a", "b")
val javaSet = scalaSet.asJava
// javaSet: java.util.Set[String] = [a, b]
javaSet.asScala
// scala.collection.mutable.Set[String] = Set(a, b)
In Scala 2.12 it is possible to use : scala.collection.JavaConverters.setAsJavaSet(scalaSetInstance)