Saturday, March 1, 2008

Scala Object Literals

Groovy has great object literals. See, for example, the Customer constructor call here. Unless I've missed it, Scala can't quite do that. So far as I can tell, you can only get inside the context of a class within a class body. Sort of like Java.

That's good and bad. It's bad because you can't construct objects easily without making new classes, and we all know what classes do to jar file sizes (even with pack200, so I guess I should add another $20 JVM bounty or something on inlined nested class definitions in the bytecode, something again that more than Scala can benefit from). But on the good side, it means that there are fewer ways to get things done. Fewer choices is sometimes better. Just swallow the bytes for consistency.

But, well, there are still a few options. Here are some examples without explanations of pros and cons or what's happening:

  trait Person1 {
def name: String
def age: Int
}
val person1 = new Person1 {
def name = "Bob"
def age = 25
}

trait Person2 extends Person1 {
var name = ""
var age = 0
}
val person2 = new Person2 {
name = "Stanley"
age = 73
}

case class Person3(name: String, age: Int) extends Person1
val person3 = Person3("Harold", 7)


I only do the "extends Person1" above to show that they are compatible at the interface level. Note also that there is no need for doubling the "{{" as in Java to write arbitrary code in a class body.

Once the object is made, you can't get back inside it again. That is, no 'with' blocks. If you go pure functional, I guess that's okay, but it would be nice to have available.

Anyway, there's another concept (and something you can do in Java with varargs, too, so remember that varargs are your friends), if you need heterogeneous lists:

  abstract class Option
case class For(name: String) extends Option
case class Name(name: String) extends Option
case class Text(text: String) extends Option

abstract class Widget
case class Button(option: Option*) extends Widget
case class Label(option: Option*) extends Widget
case class TextField(option: Option*) extends Widget
case class HBox(kids: Widget*) extends Widget
case class VBox(kids: Widget*) extends Widget

val form = VBox(
HBox(Label(Text("Age"), For("age")), TextField(Name("age"), Text(person1.age.toString))),
Button(Text("Submit"), Name("submit"))
)


And don't forget the options for inline XML:

  val xmlForm = <vbox>
<hbox><label text="Age" for="age"/><textfield name="age" text={person1.age.toString}/></hbox>
<button text="Submit" name="submit"/>
</vbox>


And that will conclude my summary of rudimentary object creation for today.

No comments:

Post a Comment