object cross-references and initialization order - scala

I have the following code:
abstract class SuperClass (cs: Seq[C]) {
def init {}
}
object A extends SuperClass(Seq(B, C))
object B extends SuperClass(Seq(A, D))
object C extends SuperClass(Seq(A, B))
object D extends SuperClass(Seq(C, B, A))
object E extends SuperClass(Seq(B, A, B))
object Initializer {
def init {
A.init
B.init
C.init
D.init
E.init
}
}
so at the beginning, because each object has inside some more things to initialize, I call
Initializer.init
and then at some point further in the program, when I use the cs parameter of an object, I get a NullPointerException because one of the objects referenced in the Seq is really null (printing out to the console shows that). Namely the references to the objects which have their init called later than the init of other objects that reference them, tend to be set to null.
This is an interesting situation. I have a supposedly any-to-any arbitrary cross-referencing here and I do not know how to properly realize the initialization without bringing it out to an external method completely (which is a break-down of encapsulation anyway). Especially that users might be given the ability to create their own singletons extending the SuperClass class.
Which is the best way to do this with as less boilerplate as possible?

I came up with the following solution. Well it's half a duplicate of Instantiating immutable paired objects, but the dependencies defined by Seq is an additional dimension.
abstract class SuperClass (cs: => Seq[SuperClass]) {
SuperClass.collected += this
def init {}
}
object SuperClass {
private val collected = ListBuffer[SuperClass]()
def init = collected.foreach(_.init)
}
object Initializer {
def init {
A // access the root object
SuperClass.init // call init on all automatically created dependent objects
}
}

Related

Singleton Object vs Companion Object in Class

I have written the following code:
class a {
object c {
var a = "STATIC"
def m() = print("STATIC METHOD")
var f = () => print("STATIC FUNCTION")
}
}
object m {
def main(args: Array[String]) = {
var o = new a()
o.c.m()
}
}
Can I say that the variables, functions and methods that are declared in object c can be static?
If I change name of object c with a then will the object becomes a companion object?
Scala has no true meaning of 'static' that Java does.
The fact that objects have a backing on the JVM that uses static methods / fields is a leaking implementation detail that you only need to deal with if using Java/JVM interop.
Unless you explicitly need that interop, you need to stop thinking of declared objects as 'static' and instead think of them as singletons within their given scope.
An inner object nested under a class, means that there is only ever going to be 1 instance of that object, for each class instance, unlike inner classes which could have multiple instances.
This applies at the top level as well, except that Scala can do additional compatibility with other JVM languages, and mark some of the methods/members as static.
Fields and methods in an object are how Scala declares things that you would have used static for in Java. I guess you can, for intuition sake, say that those fields are usually static (as in only one of those in a JVM at once).
However, in your example, you put an object inside a class, making it no longer static. You can easily check this with a few lines of code (that you can find here on Scastie).
class MyClass {
object Embedded {
val a = "field"
def m = println("method")
}
}
val a = new MyClass().Embedded
val b = new MyClass().Embedded
// prints "a and b are different objects"
if (a eq b)
println("a and b are the same object")
else
println("a and b are different objects")
Regarding your second question: no, class and object must be in the same scope in order for it to be a companion object. You can find more details on the Scala Language Specification.
I quote from there:
Generally, a companion module of a class is an object which has the same name as the class and is defined in the same scope and compilation unit. Conversely, the class is called the companion class of the module.
To answer you questions:
The methods and fields in a.c are not globally static because they need an instance of a to exist. If a were an object, a.c would be static too.
If you want to have a companion object with static fields and methods for your class a it has to be defined outside of a's code block, like this:
class a {
/* non-static stuff goes here */
}
object a {
/* static stuff goes there */
def m() = print("STATIC METHOD")
}
You must keep both in the same file, defining the object or the
class first doesn't matter, so it generally depend on a convention or what makes most sense depending on use case.
If you want to call the static method a.m inside the class a, you will still need to call it a.m and not just m. But the class a will be able to use private fields and methods of object a, because they are companions.
As others already said, static doesn't really exist in Scala, but the concept transpires from Java since Scala is in most cases compiled into java bytecode.
Last advice, the convention is usually the same in Scala and in Java for classes and object: the first-letter of their name should be uppercase (except in some advanced Scala cases)

Scala companion objects are not singleton

I have following two classes.
class A (name: String) {
}
object A {
}
According to definition of Singleton, we can have only one object of that type. However I am able to create two different objects of type A using following piece of code.
object B {
def main(args: Array[String]): Unit = {
val a = new A("Vinod")
println(a)
val b = new A("XYZ")
println(b)
}
}
can someone please explain me, where my understanding is not correct?
An object by itself is a singleton. It has its own class and no other instance of the same class exist at runtime.
However, the pattern you describe here is different: object A is not an instance of class A unless you make it so using object A extends A. You could make it the only instance of class A by making class A a sealed class, but this is unnecessary in almost all cases.
If you really want the singleton pattern, drop the class and use only object A, all of its members will be "static" in the sense of Java.
Note that the actual type of object A can be referred to as A.type, which by default is completely unrelated to type A if class A exists. Again, A.type could be a subtype of A if you explicitly make it so.
The companion object is not an instance of the companion class. They're not even the same type.
class A
object A {
var state = 0
def update() :Unit = state = state + 1
}
val abc :A = new A //instance of class A
val xyz :A.type = A //2nd reference to object A
// both reference the same singleton object
xyz.update() //res0: Unit = ()
A.state //res1: Int = 1
abc.state //Error: value state is not a member of A$A2521.this.A
the companion object can be thought of as the static space of a class. if you want to make A a singleton you can make it an object rather than a class
new A refers to class A (which is not a singleton), not to object A. You can easily check it: if you remove class A, the new A lines will no longer compile.
Also note that objects aren't necessarily singletons: they can be nested inside classes or traits, in this case there is one for each instance of the outer type.

Object extends Trait, Class extends Trait, both have to implement method

I have the following setup:
trait A
{
def doSomething(): Unit;
}
object B extends A
{
override def doSomething(): Unit =
{
// Implementation
}
}
class B(creator: String) extends A
{
override def doSomething(): Unit =
{
B.doSomething() // Now this is just completely unnecessary, but the compiler of course insists upon implementing the method
}
}
Now you may wonder why I even do this, why I let the class extend the trait as well.
The problem is, that somewhere in the Program there is a Collection of A.
So somewhere:
private val aList: ListBuffer[A] = new ListBuffer[A]
and in there, I also have to put Bs (among other derivates, namely C and D)
So I can't just let the B-class not extend it.
As the implementation is the same for all instances, I want to use an Object.
But there is also a reason I really need this Object. Because there is a class:
abstract class Worker
{
def getAType(): A
def do(): Unit =
{
getAType().doSomething()
}
}
class WorkerA
{
def getAType(): A =
{
return B
}
}
Here the singleton/object of B gets returned. This is needed for the implementation of do() in the Worker.
To summarize:
The object B is needed because of the generic implementation in do() (Worker-Class) and also because doSomething() never changes.
The class B is needed because in the collection of the BaseType A there are different instances of B with different authors.
As both the object and the class have to implement the trait for above reasons I'm in kind of a dilemma here. I couldn't find a satisfying solution that looks neater.
So, my question is (It turns out as a non-native-speaker I should've clarified this more)
Is there any way to let a class extend a trait (or class) and say that any abstract-method implementation should be looked up in the object instead of the class, so that I must only implement "doSomething()" (from the trait) once (in the object)? As I said, the trait fulfills two different tasks here.
One being a BaseType so that the collection can get instances of the class. The other being a contract to ensure the doSomething()-method is there in every object.
So the Object B needs to extend the trait, because a trait is like a Java interface and every (!) Object B (or C, or D) needs to have that method. (So the only option I see -> define an interface/trait and make sure the method is there)
edit: In case anyone wonders. How I really solved the problem: I implemented two traits.
Now for one class (where I need it) I extend both and for the other I only extend one. So I actually never have to implement any method that is not absolutely necessary :)
As I wrote in the comment section, it's really unclear to me what you're asking.
However, looking at your code examples, it seems to me that trait A isn't really required.
You can use the types that already come with the Scala SDK:
object B extends (()=>Unit) {
def apply() { /* implementation */ }
}
Or, as a variant:
object B {
val aType:()=>Unit = {() => /* implementation */ }
}
In the first case, you can access the singleton instance with B, in the second case with B.aType.
In the second case, no explicit declaration of the apply method is needed.
Pick what you like.
The essential message is: You don't need a trait if you just define one simple method.
That's what Scala functions are for.
The list type might look like this:
private val aList:ListBuffer[()=>Unit] = ???
(By the way: Why not declare it as Seq[()=>Unit]? Is it important to the caller that it is a ListBuffer and not some other kind of sequence?)
Your worker might then look like this:
abstract class Worker {
def aType:()=>Unit // no need for the `get` prefix here, or the empty parameter list
def do() {aType()}
}
Note that now the Worker type has become a class that offers a method that invokes a function.
So, there is really no need to have a Worker class.
You can just take the function (aType) directly and invoke it, just so.
If you always want to call the implementation in object B, well - just do that then.
There is no need to wrap the call in instances of other types.
Your example class B just forwards the call to the B object, which is really unnecessary.
There is no need to even create an instance of B.
It does have the private member variable creator, but since it's never used, it will never be accessed in any way.
So, I would recommend to completely remove the class B.
All you need is the type ()=>Unit, which is exactly what you need: A function that takes no parameters and returns nothing.
If you get tired of writing ()=>Unit all the time, you can define a type alias, for example inside the package object.
Here is my recommentation:
type SideEffect = ()=>Unit
Then you can use SideEffect as an alias for ()=>Unit.
That's all I can make of it.
It looks to me that this is probably not what you were looking for.
But maybe this will help you a little bit along the way.
If you want to have a more concrete answer, it would be nice if you would clarify the question.
object B doesn't really have much to do with class B aside from some special rules.
If you wish to reuse that doSomething method you should just reuse the implementation from the object:
class B {
def doSomething() = B.doSomething()
}
If you want to specify object B as a specific instance of class B then you should do the following:
object B extends B("some particular creator") {
...
}
You also do not need override modifiers although they can be handy for compiler checks.
The notion of a companion object extending a trait is useful for defining behavior associated with the class itself (e.g. static methods) as opposed to instances of the class. In other words, it allows your static methods to implement interfaces. Here's an example:
import java.nio.ByteBuffer
// a trait to be implemented by the companion object of a class
// to convey the fixed size of any instance of that class
trait Sized { def size: Int }
// create a buffer based on the size information provided by the
// companion object
def createBuffer(sized: Sized): ByteBuffer = ByteBuffer.allocate(sized.size)
class MyClass(x: Long) {
def writeTo(buffer: ByteBuffer) { buffer.putLong(x) }
}
object MyClass extends Sized {
def size = java.lang.Long.SIZE / java.lang.Byte.SIZE
}
// create a buffer with correct sizing for MyClass whose companion
// object implements Sized. Note that we don't need an instance
// of MyClass to obtain sizing information.
val buf = createBuffer(MyClass)
// write an instance of MyClass to the buffer.
val c = new MyClass(42)
c.writeTo(buf)

Force initialization of Scala singleton object

I'm working on an automatic mapping framework built on top of Dozer. I won't go into specifics as it's not relevant to the question but in general it's supposed to allow easy transformation from class A to class B. I'd like to register the projections from a class's companion object.
Below is a (simplified) example of how I want this to work, and a Specs test that assures that the projection is being registered properly.
Unfortunately, this doesn't work. From what I can gather, this is because nothing initializes the A companion object. And indeed, if I call any method on the A object (like the commented-out hashCode call, the projection is being registered correctly.
My question is - how can I cause the A object to be initialized automatically, as soon as the JVM starts? I don't mind extending a Trait or something, if necessary.
Thanks.
class A {
var data: String = _
}
class B {
var data: String = _
}
object A {
projekt[A].to[B]
}
"dozer projektor" should {
"transform a simple bean" in {
// A.hashCode
val a = new A
a.data = "text"
val b = a.-->[B]
b.data must_== a.data
}
}
Short answer: You can't. Scala objects are lazy, and are not initialized until first reference. You could reference the object, but then you need a way of ensuring the executing code gets executed, reducing the problem back to the original problem.
In ended up doing this:
trait ProjektionAware with DelayedInit
{
private val initCode = new ListBuffer[() => Unit]
override def delayedInit(body: => Unit)
{
initCode += (() => body)
}
def registerProjektions()
{
for (proc <- initCode) proc()
}
}
object A extends ProjektionAware {
projekt[A].to[B]
}
Now I can use a classpath scanning library to initialize all instances of ProjektionAware on application bootstrap. Not ideal, but works for me.
You can force the instantiation of A to involve the companion object by using an apply() method or some other sort of factory method defined in the object instead of directly using the new A() constructor.
This does not cause the object to be initialized when the JVM starts, which I think as noted in another answer can't generally be done.
As Dave Griffith and Don Roby already noted, it cannot be done at JVM startup in general. However maybe this initialization could wait until first use of your framework?
If so, and if you don't mind resorting to fragile reflection tricks, in your --> method you could obtain reference to the companion object and get it initialize itself.
You can start at Getting object instance by string name in scala.
We could use this sort of a way to ensure that companion object gets initialized first and then the class gets instantiated.
object B {
val i = 0
def apply(): B = new B()
}
class B {
// some method that uses i from Object B
def show = println(B.i)
}
// b first references Object B which calls apply()
// then class B is instantiated
val b = B()

How do I declare a constructor for an 'object' class type in Scala? I.e., a one time operation for the singleton

I know that objects are treated pretty much like singletons in scala. However, I have been unable to find an elegant way to specify default behavior on initial instantiation. I can accomplish this by just putting code into the body of the object declaration but this seems overly hacky. Using an apply doesn't really work because it can be called multiple times and doesn't really make sense for this use case.
Any ideas on how to do this?
Classes and objects both run the code in their body upon instantiation, by design. Why is this "hacky"? It's how the language is supposed to work. If you like extra braces, you can always use them (and they'll keep local variables from being preserved and world-viewable).
object Initialized {
// Initalization block
{
val someStrings = List("A","Be","Sea")
someStrings.filter(_.contains('e')).foreach(s => println("Contains e: " + s))
}
def doSomething { println("I was initialized before you saw this.") }
}
scala> Initialized.doSomething
Contains e: Be
Contains e: Sea
I was initialized before you saw this.
scala> Initialized.someStrings
<console>:9: error: value someStrings is not a member of object Initialized
Initialized.someStrings
Rex has it right, I just wanted to point out a pattern I use a lot, that saves you from having to use vars, while avoiding namespace pollution by intermediate values.
object Foo {
val somethingFooNeeds = {
val intermediate = expensiveCalculation
val something = transform(intermediate)
something
}
}
If it makes you feel better, you can create some class with protected constructor and object will create singleton of this class:
sealed class MyClass protected (val a: String, b: Int) {
def doStuff = a + b
}
object MyObject extends MyClass("Hello", b = 1)
Also notice, that sealed stops other classes and objects to extend MyClass and protected will not allow creation of other MyClass instances.
But I personally don't see any problems with some code in the body of the object. You can also create some method like init and just call it:
object MyObject {
init()
def init() {
...
}
}
The body of object and class declarations IS the default constructor and any code placed in there will be executed upon first reference, so that is exactly the way to do it.