On Sat, Oct 20, 2012 at 9:59 PM, Bruce Eckel <
bruce...@gmail.com> wrote:
> I got this from the second answer at:
>
http://stackoverflow.com/questions/1898932/case-classes-vs-enumerations-in-scala
>
> First, the example. This runs:
>
> trait Enum[A] {
> trait Value { self: A =>
> _values :+= this
> }
> private var _values = List.empty[A]
> def values = _values
> }
>
> sealed trait Currency extends Currency.Value
> object Currency extends Enum[Currency] {
> case object EUR extends Currency
> case object GBP extends Currency
> }
>
> println(Currency.values)
>
> My first problem is trying to figure out the syntax of:
>
> trait Value { self: A =>
> _values :+= this
> }
>
> From the context, I'm guessing that the code after the => somehow runs for
> every object that's created. But how do you read/mentally parse "self: A=>"?
That's not related, really. "self: A =>" is a self type, which is just
a way of creating an alias for "this" and/or adding a requirement to
the concrete implementations of the trait (that is, they must extend
"A", directly or indirectly).
What comes after that is just your regular primary constructor.
> My second problem is that the code in Value doesn't seem to execute; the
> output of the println is List(). What's the correct way to do this?
An object is lazily initialized, pretty much like a lazy val. A
declaration like "case object EUR extends Currency" is a lot like
"lazy val EUR = new Currency with Singleton".
Since you have not used any of those objects, they have not been
initialized. As to how to do that correctly, that is, imho, one of
Scala's unsolved hurdles.
--
Daniel C. Sobral
I travel to the future all the time.