- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
How to force initialization of inner objects?
Hello,
I'd like to have all inner objects created when their outer class is instanciated.
For example, if I have:
class Funny {
private var reg = List[AnyRef]()
object name extends AnyRef {
reg = this :: reg
}
def describe = {
reg mkString
}
}
Then I'd like " (new Funny) describe" to print the list of inner objects but since object are lazy initialized, the list is empty...
Is there any simple way to do that?
Thanks,
Sebastien
I'd like to have all inner objects created when their outer class is instanciated.
For example, if I have:
class Funny {
private var reg = List[AnyRef]()
object name extends AnyRef {
reg = this :: reg
}
def describe = {
reg mkString
}
}
Then I'd like " (new Funny) describe" to print the list of inner objects but since object are lazy initialized, the list is empty...
Is there any simple way to do that?
Thanks,
Sebastien










Re: How to force initialization of inner objects?
On Thu, Dec 18, 2008 at 15:32, Sebastien Bocq <sebastien [dot] bocq [at] gmail [dot] com> wrote:
name
Re: How to force initialization of inner objects?
I thought naively that reflection would help but it does not initialize the fields, I'm getting null's on the console with the sample below.
trait InitObjects {
def init(a:AnyRef) {
for (f <- this.getClass.getDeclaredFields) {
f.setAccessible(true)
println(f.getType)
println(f.get(this))
}
}
}
class Funny extends InitObjects {
init(this)
private var reg = List[String]()
object name {
reg = this.getClass.getSimpleName :: reg
}
def describe = {
reg mkString
}
}
scala> new Funny
class line8$object$$iw$$iw$$iw$Funny$name$
null
class scala.List
null
res5: Funny = Funny@7afcba
Thanks the help,
Sebastien
2008/12/18 Lukas Rytz <lukas [dot] rytz [at] epfl [dot] ch>
Re: How to force initialization of inner objects?
On Thu, Dec 18, 2008 at 11:04 AM, Sebastien Bocq <sebastien [dot] bocq [at] gmail [dot] com> wrote:
Re: How to force initialization of inner objects?
trait EarlyBird {
for (f <- this.getClass.getDeclaredMethods) {
if (f.getParameterTypes().length == 0 && classOf[Var].isAssignableFrom(f.getReturnType())) {
f.invoke(this)
}
}
}
object Registry {
var l = List[String]()
}
abstract class Var {
Registry.l = this.getClass.getSimpleName :: Registry.l
}
class Funny extends EarlyBird {
object name extends Var
}
// scala> new Funny
// scala> Registry.l.mkString
// res1: String = Funny$name$
This works but there is one last thing worrying me, is it safe to assume that this pattern won't break with new releases of Scala?
Thanks,
Sebastien
Re: How to force initialization of inner objects?
On Fri, Dec 19, 2008 at 11:21 AM, Sebastien Bocq
<sebastien [dot] bocq [at] gmail [dot] com> wrote:
> Thanks you all for the advice, it works now. javap shows that the field
> corresponding to the inner object is initialized with a new instance of
> Funny$name in the name() method is invoked. Therefore I used reflection to
> invoke all the methods that return a specific type inherited by my inner
> objects like in the sample below.
>
> trait EarlyBird {
> for (f <- this.getClass.getDeclaredMethods) {
> if (f.getParameterTypes().length == 0 &&
> classOf[Var].isAssignableFrom(f.getReturnType())) {
> f.invoke(this)
> }
> }
> }
>
> object Registry {
> var l = List[String]()
> }
>
> abstract class Var {
> Registry.l = this.getClass.getSimpleName :: Registry.l
> }
>
> class Funny extends EarlyBird {
>
> object name extends Var
>
> }
>
> // scala> new Funny
> // scala> Registry.l.mkString
> // res1: String = Funny$name$
>
> This works but there is one last thing worrying me, is it safe to assume
> that this pattern won't break with new releases of Scala?
Hard to say. Scala has many features that are difficult to translate
to the JVM, and specifying the implementation details would be too
limiting and make things even harder. The Scala Language Specification
says that an object definition is 'roughly equivalent' to a field and
an accessor method that instantiates the object on first access. Your
code seems to rely on the assumption that there's one method per
object that returns a subtype of 'Var', and that there are no other
methods with this signature. It will probably work with future
versions of Scala. But I don't know about future versions of your own
code :)
There are plans to reimplement objects in terms of lazy values. That
will change the way objects are represented in bytecode, although
there will still be an accessor method with the right name.
Cheers,
Iulian
>
> Thanks,
> Sebastien
>
Re: How to force initialization of inner objects?
private var reg = List[AnyRef]()
val name = new AnyRef {
reg = this.reg
}
def describe = {
reg mkString
}
}
On Thu, Dec 18, 2008 at 6:32 AM, Sebastien Bocq <sebastien [dot] bocq [at] gmail [dot] com> wrote:
Re: How to force initialization of inner objects?
class Funny {
private var reg = List[String]()
object name {
reg = this.getClass.getSimpleName :: reg
};name
def describe = {
reg mkString // returns Funny$name
}
}
Now, I'm investigating if I can make Funny inherit from a trait that uses reflection to initialize the inner objects, not sure if it'll work...
Re: How to force initialization of inner objects?
Run "javap -private Funny" to see the inner object member references, you'll see something like this if I remember correctly:
private Funny$name$ name$module;
and just referencing the class though reflection (Class.forName) I believe was enough to trigger initialization.
alex