This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Re: trait vals initialization order

1 reply
Marcelo Fukushima
Joined: 2009-01-09,
User offline. Last seen 42 years 45 weeks ago.

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
>

Jorge Ortiz
Joined: 2008-12-16,
User offline. Last seen 29 weeks 3 days ago.
Re: trait vals initialization order
I believe there's no good way for the compiler to automatically figure out the correct initialization order.

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:
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 <deanwampler@gmail.com> 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 <takeshi10@gmail.com> 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
>



--
[]'s
Marcelo Takeshi Fukushima

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland