Is it possible to validate arguments in an overloaded constructor before calling the default one? E.g. assume that my class has a default constructor
Clazz(foo: String, bar: String)
And I would like to provide another constructor
def this(fooBar: String) {
//validate if fooBar is of form FOO-BAR, if not, throw some custom exception, else invoke
this(fooBar.split("-")(0), fooBar.split("-")(1))
}
Is it possible to somehow perform the validation?
Auxiliary constructors in Scala have to invoke another constructor as the first thing they do, see the Scala Language Reference, Section 5.3.1, p. 74 or Scala constructor overload? So, validation of arguments in the way suggested is not possible.
See also Why can auxiliary constructors in Scala only consist of a single call to another constructor? The book "Programming in Scala" by Odersky, Spoon, and Venners sates the following on this topic (Section 6.7, p. 147):
If you’re familiar with Java, you may wonder why Scala’s rules for
constructors are a bit more restrictive than Java’s. In Java, a
constructor must either invoke another constructor of the same class,
or directly invoke a constructor of the superclass, as its first
action. In a Scala class, only the primary constructor can invoke a
superclass constructor. The increased restriction in Scala is really a
design trade-off that needed to be paid in exchange for the greater
conciseness and simplicity of Scala’s constructors compared to Java’s.
Superclasses and the details of how constructor invocation and
inheritance interact will be explained in Chapter 10.
As a solution to your question, you might want to consider factory objects, see, e.g., http://fupeg.blogspot.in/2008/11/scala-constructors.html or http://alvinalexander.com/scala/factory-pattern-in-scala-design-patterns This would lead to something like the following (with a more sophisticated validation, probably):
case class Clazz(foo : String, bar : String)
case class FooBarException(msg: String) extends RuntimeException(msg)
object Clazz {
def apply(fooBar : String) : Clazz =
if (fooBar.count(_ == '-') == 1)
new Clazz(fooBar.split("-")(0), fooBar.split("-")(1))
else
throw new FooBarException("not valid: " + fooBar)
}
object Test extends App {
val c1 = Clazz("foo", "bar")
println(c1)
val c2 = Clazz("foo-bar")
println(c2)
try {
val c3 = Clazz("will throw error")
} catch {
case FooBarException(msg) => println(msg)
}
}
Related
I think I see the merit in defining auxiliary constructors in such a way that the primary constructor is the solitary point of entry to the class. But why can't I do something like this?
class Wibble(foo: Int, bar: String) {
def this(baz: List[Any]) = {
val bazLength = baz.length
val someText = "baz length is " ++ bazLength.toString
this(bazLength, someText)
}
}
Is it maybe a way of guaranteeing that the auxiliary constructor doesn't have side effects and/or can't return early?
Auxiliary constructors can contain more than a single invocation of another constructor, but their first statement must be said invocation.
As explained in Programming in Scala, ch. 6.7:
In Scala, every auxiliary constructor must invoke another constructor of
the same class as its first action. In other words, the first statement in every
auxiliary constructor in every Scala class will have the form this(. . . ).
The invoked constructor is either the primary constructor (as in the Rational
example), or another auxiliary constructor that comes textually before the
calling constructor. The net effect of this rule is that every constructor invocation
in Scala will end up eventually calling the primary constructor of the
class. The primary constructor is thus the single point of entry of a class.
If you’re familiar with Java, you may wonder why Scala’s rules for
constructors are a bit more restrictive than Java’s. In Java, a constructor
must either invoke another constructor of the same class, or directly invoke
a constructor of the superclass, as its first action. In a Scala class, only the
primary constructor can invoke a superclass constructor. The increased
restriction in Scala is really a design trade-off that needed to be paid in
exchange for the greater conciseness and simplicity of Scala’s constructors
compared to Java’s.
Just as in Java, one can get round this limitation by extracting the code to be executed before the primary constructor call into a separate method. In Scala it is a bit more tricky than in Java, as apparently you need to move this helper method into the companion object in order to be allowed to call it from the constructor.
Moreover, your specific case is awkward as you have two constructor parameters and - although one can return tuples from a function - this returned tuple is then not accepted as the argument list to the primary constructor. For ordinary functions, you can use tupled, but alas, this doesn't seem to work for constructors. A workaround would be to add yet another auxiliary constructor:
object Wibble {
private def init(baz: List[Any]): (Int, String) = {
val bazLength = baz.length
val someText = "baz length is " ++ bazLength.toString
println("init")
(bazLength, someText)
}
}
class Wibble(foo: Int, bar: String) {
println("Wibble wobble")
def this(t: (Int, String)) = {
this(t._1, t._2)
println("You can execute more code here")
}
def this(baz: List[Any]) = {
this(Wibble.init(baz))
println("You can also execute some code here")
}
}
This at least works, even if it is slightly complicated.
scala> val w = new Wibble(List(1, 2, 3))
init
Wibble wobble
You can execute more code here
You can also execute some code here
w: Wibble = Wibble#b6e385
Update
As #sschaef's pointed out in his comment, this can be simplified using a factory method in the companion object:
object Wobble {
def apply(baz: List[Any]): Wobble = {
val bazLength = baz.length
val someText = "baz length is " ++ bazLength.toString
println("init")
new Wobble(bazLength, someText)
}
}
class Wobble(foo: Int, bar: String) {
println("Wobble wibble")
}
Thus we need no new to create an object anymore:
scala> val w = Wobble(List(1, 2, 3))
init
Wobble wibble
w: Wobble = Wobble#47c130
I'm writing a message parser. Suppose I have a superclass Message with two auxiliary constructors, one that accepts String raw messages and one that accepts a Map with datafields mapped out in key-value pairs.
class Message {
def this(s: String)
def this(m: Map[String, String])
def toRaw = { ... } # call third party lib to return the generated msg
def map # call third party lib to return the parsed message
def something1 # something common for all messages which would be overriden in child classes
def something2 # something common for all messages which would be overriden in child classes
...
}
There's good reason to do this as the library that does parsing/generating is kind of awkward and removing the complexity of interfacing with it into a separate class makes sense, the child class would look something like this:
class SomeMessage extends Message {
def something1 # ...
def something2 # ...
}
and the idea is to use the overloaded constructors in the child class, for example:
val msg = new SomeMessage(rawMessage) # or
val msg = new SomeMessage("fld1" -> ".....", "fld2" -> "....")
# and then be able to call
msg.something1
msg.something2 # ...
However, the way auxiliary constructors and inheritance seem to behave in Scala this pattern has proven to be pretty challenging, and the simplest solution I found so far is to create a method called constructMe, which does the work of the constructors in the above case:
val msg = new SomeMessage
msg.constructMe(rawMessage) # or
msg.constructMe("fld1" -> ".....", "fld2" -> "....")
which seems crazy to need a method called constructMe.
So, the question:
is there a way to structure the code so to simply use the overloaded constructors from the superclass? For example:
val msg = new SomeMessage(rawMessage) # or
val msg = new SomeMessage("fld1" -> ".....", "fld2" -> "....")
or am I simply approaching the problem the wrong way?
Unless I'm missing something, you are calling the constructor like this:
val msg = new SomeMessage(rawMessage)
But the Message class doesn't not take a parameter, your class should be defined so:
class Message(val message: String) {
def this(m: Map[String, String]) = this("some value from mapping")
}
Also note that the constructor in scala must call the primary constructor as first action, see this question for more info.
And then the class extending the Message class should be like this:
class SomeMessage(val someString: String) extends Message(someString) {
def this(m: Map[String, String]) = this("this is a SomeMessage")
}
Note that the constructor needs a code block otherwise your code won't compile, you can't have a definition like def this(someString: String) without providing the implementation.
Edit:
To be honest I don't quite get why you want to use Maps in your architecture, your class main point it to contain a String, having to do with complex types in constructors can lead to problems. Let's say you have some class which can take a Map[String, String] as a constructor parameter, what will you do with it? As I said a constructor must call himself as first instruction, what you could is something like this:
class A(someString: String) = {
def this(map: Map[String, String]) = this(map.toString)
}
And that's it, the restrictions in scala don't allow you to do anything more, you would want to do some validation, for example let's say you want to take always the second element in the map, this could throw exceptions since the user is not forced to provide a map with more than one value, he's not even forced to provide a filled map unless you start filling your class with requires.
In your case I probably would leave String as class parameter or maybe a List[String] where you can call mkString or toString.
Anyway if you are satisfied calling map.toString you have to give both constructor implementation to parent and child class, this is one of scala constructor restrictions (in Java you could approach the problem in a different way), I hope somebody will prove me wrong, but as far as I know there's no other way to do it.
As a side note, I personally find this kind of restriction to be correct (most of the time) since the force you to structure your code to be more rigorous and have a better architecture, think about the fact that allowing people to do whatever they want in a constructor (like in java) obfuscate their true purpose, that is return a new instance of a class.
I think I see the merit in defining auxiliary constructors in such a way that the primary constructor is the solitary point of entry to the class. But why can't I do something like this?
class Wibble(foo: Int, bar: String) {
def this(baz: List[Any]) = {
val bazLength = baz.length
val someText = "baz length is " ++ bazLength.toString
this(bazLength, someText)
}
}
Is it maybe a way of guaranteeing that the auxiliary constructor doesn't have side effects and/or can't return early?
Auxiliary constructors can contain more than a single invocation of another constructor, but their first statement must be said invocation.
As explained in Programming in Scala, ch. 6.7:
In Scala, every auxiliary constructor must invoke another constructor of
the same class as its first action. In other words, the first statement in every
auxiliary constructor in every Scala class will have the form this(. . . ).
The invoked constructor is either the primary constructor (as in the Rational
example), or another auxiliary constructor that comes textually before the
calling constructor. The net effect of this rule is that every constructor invocation
in Scala will end up eventually calling the primary constructor of the
class. The primary constructor is thus the single point of entry of a class.
If you’re familiar with Java, you may wonder why Scala’s rules for
constructors are a bit more restrictive than Java’s. In Java, a constructor
must either invoke another constructor of the same class, or directly invoke
a constructor of the superclass, as its first action. In a Scala class, only the
primary constructor can invoke a superclass constructor. The increased
restriction in Scala is really a design trade-off that needed to be paid in
exchange for the greater conciseness and simplicity of Scala’s constructors
compared to Java’s.
Just as in Java, one can get round this limitation by extracting the code to be executed before the primary constructor call into a separate method. In Scala it is a bit more tricky than in Java, as apparently you need to move this helper method into the companion object in order to be allowed to call it from the constructor.
Moreover, your specific case is awkward as you have two constructor parameters and - although one can return tuples from a function - this returned tuple is then not accepted as the argument list to the primary constructor. For ordinary functions, you can use tupled, but alas, this doesn't seem to work for constructors. A workaround would be to add yet another auxiliary constructor:
object Wibble {
private def init(baz: List[Any]): (Int, String) = {
val bazLength = baz.length
val someText = "baz length is " ++ bazLength.toString
println("init")
(bazLength, someText)
}
}
class Wibble(foo: Int, bar: String) {
println("Wibble wobble")
def this(t: (Int, String)) = {
this(t._1, t._2)
println("You can execute more code here")
}
def this(baz: List[Any]) = {
this(Wibble.init(baz))
println("You can also execute some code here")
}
}
This at least works, even if it is slightly complicated.
scala> val w = new Wibble(List(1, 2, 3))
init
Wibble wobble
You can execute more code here
You can also execute some code here
w: Wibble = Wibble#b6e385
Update
As #sschaef's pointed out in his comment, this can be simplified using a factory method in the companion object:
object Wobble {
def apply(baz: List[Any]): Wobble = {
val bazLength = baz.length
val someText = "baz length is " ++ bazLength.toString
println("init")
new Wobble(bazLength, someText)
}
}
class Wobble(foo: Int, bar: String) {
println("Wobble wibble")
}
Thus we need no new to create an object anymore:
scala> val w = Wobble(List(1, 2, 3))
init
Wobble wibble
w: Wobble = Wobble#47c130
In Scala what is the reason that you don't need to use "new" to create a new "case class"?
I tried searching for awhile now without answers.
Do you want the how or the why? As the other answer notes, the how is just the apply method on the automatically generated companion object.
For the why: case classes are often used to implement algebraic data types in Scala, and the new-less constructor allows code that is more elegant (creating a value looks more like deconstructing it via pattern matching, for example) and that more closely resembles ADT syntax in other languages.
Case class has prebuilt companion object with apply() implemented. Someone even complains about this: How to override apply in a case class companion :)
Case classes provide you with an automatically generated apply function on their companion object that you can use like a constructor.
In Scala decompiled byte code you will find apply function created as the following :
object Person {
def apply(name: String, age: Integer): Person = new Person(name,age)
}
Example :
case class Person(name: String, age: Integer)
The following three all do the same thing.
val p0 = new Person("Frank", 23) // normal constructor
val p1 = Person("Frank", 23) // this uses apply
val p2 = Person.apply("Frank", 23) // using apply manually
So if you use val p1 = Person("Frank", 23) it is not a constructor, this a method that call apply method.
Please read scala-object-apply-functions for more info.
I'm trying to get a better grasp of structural type dispatch. For instance, assume I have an iterable object with a summary method that computes the mean. So o.summary() gives the mean value of the list. I might like to use structural type dispatch to enable summary(o).
Is there a set of best practices regarding o.summary() vs. summary(o)?
How does scala resolve summary(o) if I have a method summary(o: ObjectType) and summary(o: { def summary: Double})
How does structural type dispatch differ from multimethods or generic functions?
Michael Galpin gives the following discription about structural type dispatch:
Structural types are Scala’s version of “responds-to” style programming as seen in many dynamic languages. So like
def sayName ( x : { def name:String }){
println(x.name)
}
Then any object with a method called name that takes no parameters and returns a string, can be passed to sayName:
case class Person(name:String)
val dean = Person("Dean")
sayName(dean) // Dean
-- 1. In your example, I wouldn't use the summary(o) version, as this is not a very object oriented style of programming. When calling o.summary (you could drop the brackets as it has no side-effects), you are asking for the summary property of o. When calling summary(o), you are passing o to a method that calculates the summary of o. I believe that the first approach is nicer :).
I haven't used structural type dispatch much, but I assume that it is best suited (in a large system) for the case where you would have to write an interface just because one method wants a type that has some method defined. Sometimes creating that interface and forcing the clients to implement it can be awkward. Sometimes you want to use a client defined in another API which conforms to your interface but doesn't explicitly implement it. So, in my opinion, structural type dispatch serves as a nice way to make the adapter pattern implicitly (saves on boilerplate, yay!).
-- 2. Apparently if you call summary(o) and o is of ObjectType, summary(o: ObjectType) gets called (which does make sense). If you call summary(bar), in which bar is not of ObjectType, two things can happen. The call compiles if bar has the method summary() of the right signature and name or otherwise, the call doesn't compile.
Example:
scala> case class ObjectType(summary: Double)
defined class ObjectType
scala> val o = ObjectType(1.2)
o: ObjectType = ObjectType(1.2)
scala> object Test {
| def summary(o: ObjectType) { println("1") }
| def summary(o: { def summary: Double}) { println("2")}
| }
defined module Test
scala> Test.summary(o)
1
Unfortunately, something like the following does not compile due to type erasure:
scala> object Test{
| def foo(a: {def a: Int}) { println("A") }
| def foo(b: {def b: Int}) { println("B") }
| }
:6: error: double definition:
method foo:(AnyRef{def b(): Int})Unit and
method foo:(AnyRef{def a(): Int})Unit at line 5
have same type after erasure: (java.lang.Object)Unit
def foo(b: {def b: Int}) { println("B") }
-- 3. In a sense, structural type dispatch is more dynamic than generic methods, and also serves a different purpose. In a generic method you can say either: a. I want something of any type; b. I want something of a type that is a subtype of A; c. I'll take something that is a supertype of B; d. I'll take something that has an implicit conversion to type C. All of these are much stricter than just "I want a type that has the method foo with the right signature". Also, structural type dispatch does use reflection, as they are implemented by type erasure.
I don't know much about multimethods, but looking at the wikipedia article, it seems that multimethods in Scala can be achieved using pattern matching. Example:
def collide(a: Collider, b: Collider) = (a, b) match {
case (asteroid: Asteroid, spaceship: Spaceship) => // ...
case (asteroid1: Asteroid, asteroid2: Asteroid) => // ...
...
Again, you could use structural type dispatch - def collide(a: {def processCollision()}), but that depends on a design decision (and I would create an interface in this example).
-- Flaviu Cipcigan
Structural data types aren't really all that useful. That's not to say they are useless, but they definitely a niche thing.
For instance, you might want to write a generic test case for the "size" of something. You might do it like this:
def hasSize(o: { def size: Int }, s: Int): Boolean = {
o.size == s
}
This can then be used with any object that implements the "size" method, no matter its class hierarchy.
Now, they are NOT structural type dispatches. They are NOT related to dispatching, but to type definition.
And Scala is an object oriented language always. You must call methods on objects. Function calls are actually "apply" method calls. Things like "println" are just members of objects imported into scope.
I think you asked what Scala does with a call on a structural type. It uses reflection. For example, consider
def repeat(x: { def quack(): Unit }, n: Int) {
for (i <- 1 to n) x.quack()
}
The call x.quack() is compiled into a lookup of the quack method, and then a call, both using Java reflection. (You can verify that by looking at the byte codes with javap. Look for a class with a funny name like Example$$anonfun$repeat$1.)
If you think about it, it's not surprising. There is no way of making a regular method call because there is no common interface or superclass.
So, the other respondents were absolutely right that you don't want to do this unless you must. The cost is very high.