- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Re: trait vals initialization order
Tue, 2009-01-13, 18:11
yep i know that - and adding lazy was the fix to my code
the ideal scenario would be if the compiler could see these
dependencies and put things in the right order - or fail if that could
not be done in case of circular dependencies
On Tue, Jan 13, 2009 at 2:33 PM, Dean Wampler wrote:
> The problem is that "first" is initialized when the body of the trait
> is evaluated in the construction process. So, for example, if you
> tried this:
>
> new A {
> val list = List("first", "second")
> }
>
> A's body is evaluated before the anonymous class body, where "list" is
> defined, just as any parent class constructor is evaluated before the
> derived class constructor. Inside A, the list is null.
>
> However, if you declare "lazy val first", then "list.firstOption"
> won't be called until "first" is actually used. (Changing "val first"
> to "def first" would do the same thing, except "list.firstOption"
> would be called everytime "first" is called, not just one time.)
>
> Make sense?
>
> dean
>
> On Tue, Jan 13, 2009 at 9:10 AM, Marcelo Fukushima wrote:
>> Hello again (it seens i always send emails to complain, but what can i do?)
>>
>> I think ive found a bug, but since i couldnt find it in Trac, it might
>> just be intentional
>>
>> consider a simple trait:
>>
>>
>> trait A {
>> val list: List[String] //any non "constant" value
>>
>> val first = list.firstOption //any method will do
>> }
>>
>> all implementations of this trait throws NullPointerException - at
>> least in 2.7.2-final and 2.7.3-RC2. Is this intended? If not, it
>> happens like this because the trait $init method is called before the
>> assignment for the generated list field
>>
>> thanks for the attention
>> --
>> []'s
>> Marcelo Takeshi Fukushima
>>
>
>
>
> --
> Dean Wampler
> http://www.objectmentor.com
> http://www.polyglotprogramming.com
> http://www.aspectprogramming.com
> http://aquarium.rubyforge.org
> http://www.contract4j.org
>
You can use an early initialization block though.
new { val list = List("first", "second") } with A
Likewise
abstract class B
class AA extends { val list = List("first", "second") } with B with A
--j
On Tue, Jan 13, 2009 at 9:10 AM, Marcelo Fukushima <takeshi10@gmail.com> wrote: