Using Scala, in a Play 2.0 project, I am trying to grab data from a config file.
At present I use the following code to extract a String:
val foo = Play.current.configuration.getString("foo")
I had expected to get a String object back, but instead an Option[String] object is returned.
I cannot find any Java docs describing the Option[T] object and calling the toString() returns Some( foo ).
The same happens when using the configuration methods to extract Boolean and Int values from the config - ie, Option[Boolean] and Option[Int] are returned.
Can anyone explain what this Option[T] object is and how I can access the value I want in the form that the application method call implies it will be returned?
In scala, the type Option[T] represents an optional value of the type T. If you are used to Java terms, you could refer to an Option as 'a value that might be null'.
In Play they are used when getting the configuration because the string might not be present - if you would try to read it using Java, it would return null.
To get the config string you can use getOrElse, which lets you provide a default value in case the config string doesn't exist:
val foo = Play.current.configuration.getString("foo").getOrElse("bar")
Related
Consider the case that I want to deserialize a JSON string:
def deserialize[T](json)
I can provided class that I want to apply the function explicitly while writing code like
class Person(name: String)
deserialize[Person]("""{ "name": "Jennie" }""")
But, what if I need other class, I have to provide it in my code, compile again. I want my program more flexible, it can take a config file that contains name of which class I want to use. So, when ever require a new class, I just need to write the class definition, build it into another jar file, put it in classpath, then restart the program.
val config = ConfigLoader.load("config.txt")
val className = config.getString("class-to-deserialize")
deserialize[<from className to type>](json)
So, is it possible to do that in scala?
No. But because of type erasure, if you have a function def deserialize[T](json: String), its behavior can't depend on T in the first place and it doesn't matter what you pass as the type parameter. You may just need to add a cast at the end.
What is possible is to write such a function which also accepts an implicit ClassTag or TypeTag parameter, in which case you just need to create the parameter from class/type name, and that's entirely possible: just search for questions about this.
I have an exception:
java.lang.ClassCastException: scala.collection.immutable.Map$ cannot
be cast to scala.collection.immutable.Map
which i'm getting in this part of code:
val iterator = new CsvMapper()
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.readerFor(Map.getClass).`with`(CsvSchema.emptySchema().withHeader()).readValues(reader)
while (iterator.hasNext) {
println(iterator.next.asInstanceOf[Map[String, String]])
}
So, are there any options to avoid this issue, because this:
val iterator = new CsvMapper()
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.readerFor(Map[String,String].getClass).`with`(CsvSchema.emptySchema().withHeader()).readValues(reader)
doesn't help, because I get
[error] Unapplied methods are only converted to functions when a function type is expected.
[error] You can make this conversion explicit by writing `apply _` or `apply(_)` instead of `apply`.
Thanks in advance
As has been pointed out in the earlier comments, in general you need classOf[X[_,_]] rather than X.getClass or X[A, B].getClass for a class that takes two generic types. (instance.getClass retrieves the class of the associated instance; classOf[X] does the same for some type X when an instance isn't available. Since Map is an object and objects are also instances, it retrieves the class type of the object Map - the Map trait's companion.)
However, a second problem here is that scala.collection.immutable.Map is abstract (it's actually a trait), and so it cannot be instantiated as-is. (If you look at the type of Scala Map instances created via the companion's apply method, you'll see that they're actually instances of classes such as Map.EmptyMap or Map.Map1, etc.) As a consequence, that's why your modified code still produced an error.
However, the ultimate problem here is that you required - as you mentioned - a Java java.util.Map and not a Scala scala.collections.immutable.Map (which is what you'll get by default it you just type Map in a Scala program). Just one more thing to watch out for when converting Java code examples to Scala. ;-)
So I just learned about scala case classes, and I'm told they are used to provide a simple wrapper around a bunch of properties so that it's easier to test for equality. But now I have two questions:
Is this just the same thing as a struct in C++/C#?
Are case classes a value type or a reference type?
First note that a struct in C++ and a struct in C# are very different things.
Structures in C++ are just like regular classes but by default, their members
are public. See this post for more on this topic.
Structures in C# are value types. When passed as a parameter, they are
copied instead of passed via a pointer. This behaviour is similar to a
primitive type in Java. This behaviour is the default in C++, with any
class or struct.
Your second question has been answered in Eric's answer but the important point is that C# structures are passed completely by value (all their fields are copied) while Java/C# classes are passed via a pointer (that is passed by value). See this famous post if you want the full explanation.
Unfortunately, it is not currently possible to have a true value type in JVM bytecode. You cannot make your own type that will be fully copied everytime you pass it. And the answer is no, case classes aren't value types like C# structures. A JVM language may try to replicate the behaviour of a value type but it will be managed by the GC and passed via a pointer (that is passed by value).
To give a more direct answer, no:
Case classes are like regular classes with a few key differences.
Learn more about them on this page.
Not really. What scala case classes are most like is ... scala classes.
They actually are regular scala classes with a few additional methods, that get added to them automatically - namely, .copy on the class itself and .apply and .unapply on the companion object. They also get a nice .toString method, listing all the fields, and .equals, that compares instance members rather than the object ref.
In most other respects, they are just regular scala classes.
Scala classes are just like Java classes. Their reference is passed by value.
Scala case classes are just like scala classes, but some things are automatically generated for you:
The fields of the constructor are publicly accessible (albeit a case class is immutable by default, thus you can regard them as public final values in Java, unless you declare the fields of the case class as var)
An equals and hashCode method based on the fields of the constructor
An apply and unapply method in the companion object
A toString method showing all the values of the constructor
A copy method
Here's an example:
case class MasterOfTheUniverse(name: String, power: Int)
scala> MasterOfTheUniverse("He-Man", 100).name
res1: String = He-Man
scala> MasterOfTheUniverse("He-Man", 100).power
res2: Int = 100
scala> MasterOfTheUniverse("He-Man", 100).toString
res3: String = MasterOfTheUniverse(He-Man,100)
scala> MasterOfTheUniverse("He-Man", 100) == MasterOfTheUniverse("She-Ra", 90)
res4: Boolean = false
scala> MasterOfTheUniverse("She-Ra", 90) == MasterOfTheUniverse("She-Ra", 90)
res6: Boolean = true
scala> MasterOfTheUniverse("He-Man", 100).copy(name = "He-Manatee")
res7: MasterOfTheUniverse = MasterOfTheUniverse(He-Manatee,100)
I've just read: http://oldfashionedsoftware.com/2008/08/20/a-post-about-nothing/
As far as I understand, Null is a trait and its only instance is null.
When a method takes a Null argument, then we can only pass it a Null reference or null directly, but not any other reference, even if it is null (nullString: String = null for example).
I just wonder in which cases using this Null trait could be useful.
There is also the Nothing trait for which I don't really see any more examples.
I don't really understand either what is the difference between using Nothing and Unit as a return type, since both doesn't return any result, how to know which one to use when I have a method that performs logging for example?
Do you have usages of Unit / Null / Nothing as something else than a return type?
You only use Nothing if the method never returns (meaning it cannot complete normally by returning, it could throw an exception). Nothing is never instantiated and is there for the benefit of the type system (to quote James Iry: "The reason Scala has a bottom type is tied to its ability to express variance in type parameters."). From the article you linked to:
One other use of Nothing is as a return type for methods that never
return. It makes sense if you think about it. If a method’s return
type is Nothing, and there exists absolutely no instance of Nothing,
then such a method must never return.
Your logging method would return Unit. There is a value Unit so it can actually be returned. From the API docs:
Unit is a subtype of scala.AnyVal. There is only one value of type
Unit, (), and it is not represented by any object in the underlying
runtime system. A method with return type Unit is analogous to a Java
method which is declared void.
The article you quote can be misleading. The Null type is there for compatibility with the Java virtual machine, and Java in particular.
We must consider that Scala:
is completely object oriented: every value is an object
is strongly typed: every value must have a type
needs to handle null references to access, for example, Java libraries and code
thus it becomes necessary to define a type for the null value, which is the Null trait, and has null as its only instance.
There is nothing especially useful in the Null type unless you're the type-system or you're developing on the compiler. In particular I can't see any sensible reason to define a Null type parameter for a method, since you can't pass anything but null
Do you have usages of Unit / Null / Nothing as something else than a
return type?
Unit can be used like this:
def execute(code: => Unit):Unit = {
// do something before
code
// do something after
}
This allows you to pass in an arbitrary block of code to be executed.
Null might be used as a bottom type for any value that is nullable. An example is this:
implicit def zeroNull[B >: Null] =
new Zero[B] { def apply = null }
Nothing is used in the definition of None
object None extends Option[Nothing]
This allows you to assign a None to any type of Option because Nothing 'extends' everything.
val x:Option[String] = None
if you use Nothing, there is no things to do (include print console)
if you do something, use output type Unit
object Run extends App {
//def sayHello(): Nothing = println("hello?")
def sayHello(): Unit = println("hello?")
sayHello()
}
... then how to use Nothing?
trait Option[E]
case class Some[E](value: E) extends Option[E]
case object None extends Option[Nothing]
I've never actually used the Null type, but you use Unit, where you would on java use void. Nothing is a special type, because as Nathan already mentioned, there can be no instance of Nothing. Nothing is a so called bottom-type, which means, that it is a sub-type of any other type. This (and the contravariant type parameter) is why you can prepend any value to Nil - which is a List[Nothing] - and the list will then be of this elements type. None also if of type Option[Nothing]. Every attempt to access the values inside such a container will throw an exception, because that it the only valid way to return from a method of type Nothing.
Nothing is often used implicitly. In the code below,
val b: Boolean =
if (1 > 2) false
else throw new RuntimeException("error")
the else clause is of type Nothing, which is a subclass of Boolean (as well as any other AnyVal). Thus, the whole assignment is valid to the compiler, although the else clause does not really return anything.
In terms of category theory Nothing is an initial object and Unit is a terminal object.
https://en.wikipedia.org/wiki/Initial_and_terminal_objects
Initial objects are also called coterminal or universal, and terminal objects are also called final.
If an object is both initial and terminal, it is called a zero object or null object.
Here's an example of Nothing from scala.predef:
def ??? : Nothing = throw new NotImplementedError
In case you're unfamiliar (and search engines can't search on it) ??? is Scala's placeholder function for anything that hasn't been implemented yet. Just like Kotlin's TODO.
You can use the same trick when creating mock objects: override unused methods with a custom notUsed method. The advantage of not using ??? is that you won't get compile warnings for things you never intend to implement.
I'm trying to make a EnumListField in Lift/Record/Squeryl, similar to MappedEnumList in LiftMapper. The storage type should be Long/BIGINT. I understand that if I define:
def classOfPersistentField = classOf[Long]
Then Squeryl will know it should create a BIGINT column. And I know it uses setFromAny() to set the value, passing in the Long. The one piece I don't get is:
How will it read the field's value? If it uses valueBox, it will get a Seq[Enum#Value], and it won't know how to turn that into a Long.
How do I tell Squeryl to convert my Seq[Enum#Value] to a Long, or define a "getter" that returns a Long, and that doesn't conflict with the "normal" getter(s)?
you are implementing your validation logic incorrectly. The correct way to validate a Record field is to override
def validations: List[ValidationFunction]
where ValidationFunction is a type alias
type ValidationFunction = ValueType => List[FieldError]
and in your case ValueType == String.
The next issue is your Domain trait. Because your call to validate is inlined into the class definition, it will be called when your field is constructed.