I want to run some code in the body of an scala companion object before the class is instantiated. The idea is to register a bunch of object in a Set. Here is the code
trait Delegate {
def make: Ins
}
//EDIT: Changed constructor to private
//class Ins
class Ins private()
//this is the companion object that will be registered with the InsDelegate
object Ins extends Delegate{
//here is the code that do the registration but doesn't run
InsDelegate.register(this)
override def make: Ins = {
println("This is an Ins")
new Ins()
}
}
Here is the code for the InsDelegate
object InsDelegate {
private val objectSet = new mutable.HashSet[Delegate]()
def register(obj: Delegate): Unit = objectSet.add(obj)
def getRegisteredObj: Set[Delegate] = objectSet.toSet
}
When I run this test, nothing gets printed.
object test extends App {
InsDelegate.getRegisteredObj.foreach(_.make)
}
The code that register the companion object doesn't run. I know that unlike java, in order to run the companion object code you need to instantiate the class of the object. How do I accomplish what I am trying to do???
Scala objects are lazy, so they're only constructed when first used. In your example, the test application never creates any instances, so object Ins is never constructed.
Your code should work, but you would need to create an instance of class Ins in your test code:
object test extends App {
val temp = Ins.make()
InsDelegate.getRegisteredObj.foreach(_.make)
}
Incidentally, the convention for functions with side-effects (Delegate.make) is to take parentheses; a version without parentheses indicates that the function has no side-effects, which make clearly has (registering the Ins object, creating a new Ins element).
Another Scala convention is to name factory methods apply, rather than make. If you did that, you could create new Ins class instances using Ins(), instead of Ins.make(). (Ins() is interpreted to be the same as Ins.apply().)
Update: Forgot to mention this: if you want to register Ins without creating any instances first, you will need to reference it in some way. This quickly leads to ugly solutions along the lines of:
object Ins extends Delegate{
InsDelegate.register(this)
// Dummy method to get object to register itself.
def register(): Unit = {}
override def make: Ins = {
println("This is an Ins")
new Ins()
}
}
object InsDelegate {
private val objectSet = new mutable.HashSet[Delegate]()
def register(obj: Delegate): Unit = objectSet.add(obj)
def getRegisteredObj: Set[Delegate] = objectSet.toSet
// Create delegate objects...
Ins.register()
}
However, if we're going to go to that much trouble, we might as well forego registration and add objects in the InsDelegate object:
object Ins extends Delegate{
override def make: Ins = {
println("This is an Ins")
new Ins()
}
}
object InsDelegate {
// Set of delegate objects available. Note: this is public, replaces getRegisteredObj.
val objectSet: Set[Delegate] = Set(Ins)
}
The downside is that Delegate objects no longer register themselves, but that's a blessing in disguise as you can now test delegate creation separately from testing InsDelegate.
I know that unlike java, in order to run the companion object code you need to instantiate the class of the object
Actually, your Java code would have the same result. What you need to do in both cases is to load the class, and instantiating it is just one way to do it. You can also use Class.forName, ClassLoader.loadClass, load any class which uses it somewhere in a signature... One very well-known case is (or was, before JDBC 4.0) loading JDBC drivers.
Unfortunately, in Scala the class you need to load is actually Ins$ (the class of the companion object) and instantiating Ins (or loading it in some other way) isn't necessarily enough.
Related
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)
I have created a companion object for my Scala class with an apply method in it so that I can create an instance of my class without using 'new'.
object StanfordTokenizer{
def apply() = new StanfordTokenizer()
}
class StanfordTokenizer() extends Tokenizer{
def tokenizeFile(docFile: java.io.File) = new PTBTokenizer(new FileReader(docFile), new CoreLabelTokenFactory(), "").tokenize.map(x => x.word().toLowerCase).toList
def tokenizeString(str: String) = new PTBTokenizer(new StringReader(str), new CoreLabelTokenFactory(), "").tokenize.map(x => x.word.toLowerCase()).toList
}
However when I try to instantiate the StanfordTokenizer class without 'new' e.g. StandfordTokenizer.tokenizeString(str).
I get the error
value tokenizeString is not a member of object StanfordTokenizer
However, if I explicitly include the apply method like StandfordTokenizer.apply().tokenizeString(str) it does work.
I feel like I am missing something fundamental about companion objects. Can someone shed some light on this for me?
^
It's exactly as the compiler message says. tokenizeString is a member of the class StandfordTokenizer, but not its companion object. The companion object does not inherit any methods from the class. Therefore, in order to use tokenizeString, you need an instance of StandfordTokenizer in order to call it.
StandfordTokenizer.apply creates an instance of the class StandfordTokenizer, which has the method tokenizeString. It seems as though the class StandfordTokenizer holds no real information, and won't have more than one instance. If that is true, you should probably just make it an object, and you'll be able to acquire the behavior you're looking for.
object StanfordTokenizer extends Tokenizer {
def tokenizeFile(docFile: java.io.File) = ...
def tokenizeString(str: String) = ...
}
This should work as well (as a class):
StandfordTokenizer().tokenizeString(str)
StandfordTokenizer without parenthesis does not call apply, it references the object. StandfordTokenizer() does call apply, and creates a new instance of the class. This is probably the source of your confusion.
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()
I have a trait, named Init:
package test
trait Init {
def init(): Any
}
There are some classes and an object, extends this trait:
package test
object Config extends Init {
def init() = { loadFromFile(...) }
}
class InitDb extends Init {
def init() = { initdb() }
}
When app has started, I will find all classes and objects which extends Init, and invoke their init method.
package test
object App {
def main(args: Array[String]) {
val classNames: List[String] = findAllNamesOfSubclassOf[Init]
println(classNames) // -> List(test.Config$, test.InitDb)
classNames foreach { name =>
Class.forName(name).newInstance().asInstanceOf[Init].init() // ***
}
}
}
Please note the "*" line. For test.InitDb, it's OK. But for test.Config$, when newInstance(), it throws an exception said we can't access its private method.
My problem is, how to get that object, and run its init method?
There's usually little point to doing this in Scala. Just put some code in the body of any object and it'll be executed when that object is first initialised, saving you the nasty performance hit of pre-initialising everything.
In general though, finding all subclasses of a particular type requires a full classpath scan. There are a few libraries to do this, but one of the more common is Apache's commons-discover
However... This is dynamic code, it uses reflection, and it's really NOT idiomatic. Scala has sharper tools than that, so please don't try and swing the blunt ones with such violence!
I don't totally agree with Kevin. There are some exceptions. For example I wrote a Scala desktop app. I split the core and the modules into two parts. At startup time the core loads all modules into GUI. At that time the core just gets the name of modules, it doesn't need to initialize something. Then I put all module's init code in an init() function. That function will be called when user executes the module.
#Freewind: About reflection in Scala, it's absolutely the same in Java. Just please note that the methods from Java which are used with reflection, are used for Java objects - not Scala. I'm sorry for my English. I mean those methods can not work with Scala object, trait.
For example:
var classLoader = new java.net.URLClassLoader(
Array(new File("module.jar").toURI.toURL),
/*
* need to specify parent, so we have all class instances
* in current context
*/
this.getClass.getClassLoader)
var clazz = classLoader.loadClass("test.InitDb")
if (classOf[Init].isAssignableFrom(clazz))
var an_init = clazz.newInstance.asInstanceOf[Init];
But you can not do it the opposite way:
if (clazz.isAssignableFrom(classOf[Init]))
Because Init is a trait, and Java method isAssignableFrom(Class) doesn't know trait.
I'm not sure if my question is useful for you, but here it is.
I'm just going over some Scala tutorials on the Internet and have noticed in some examples an object is declared at the start of the example.
What is the difference between class and object in Scala?
tl;dr
class C defines a class, just as in Java or C++.
object O creates a singleton object O as instance of some anonymous class; it can be used to hold static members that are not associated with instances of some class.
object O extends T makes the object O an instance of trait T; you can then pass O anywhere, a T is expected.
if there is a class C, then object C is the companion object of class C; note that the companion object is not automatically an instance of C.
Also see Scala documentation for object and class.
object as host of static members
Most often, you need an object to hold methods and values/variables that shall be available without having to first instantiate an instance of some class.
This use is closely related to static members in Java.
object A {
def twice(i: Int): Int = 2*i
}
You can then call above method using A.twice(2).
If twice were a member of some class A, then you would need to make an instance first:
class A() {
def twice(i: Int): Int = 2 * i
}
val a = new A()
a.twice(2)
You can see how redundant this is, as twice does not require any instance-specific data.
object as a special named instance
You can also use the object itself as some special instance of a class or trait.
When you do this, your object needs to extend some trait in order to become an instance of a subclass of it.
Consider the following code:
object A extends B with C {
...
}
This declaration first declares an anonymous (inaccessible) class that extends both B and C, and instantiates a single instance of this class named A.
This means A can be passed to functions expecting objects of type B or C, or B with C.
Additional Features of object
There also exist some special features of objects in Scala.
I recommend to read the official documentation.
def apply(...) enables the usual method name-less syntax of A(...)
def unapply(...) allows to create custom pattern matching extractors
if accompanying a class of the same name, the object assumes a special role when resolving implicit parameters
A class is a definition, a description. It defines a type in terms of methods and composition of other types.
An object is a singleton -- an instance of a class which is guaranteed to be unique. For every object in the code, an anonymous class is created, which inherits from whatever classes you declared object to implement. This class cannot be seen from Scala source code -- though you can get at it through reflection.
There is a relationship between object and class. An object is said to be the companion-object of a class if they share the same name. When this happens, each has access to methods of private visibility in the other. These methods are not automatically imported, though. You either have to import them explicitly, or prefix them with the class/object name.
For example:
class X {
// class X can see private members of object X
// Prefix to call
def m(x: Int) = X.f(x)
// Import and use
import X._
def n(x: Int) = f(x)
private def o = 2
}
object X {
private def f(x: Int) = x * x
// object X can see private members of class X
def g(x: X) = {
import x._
x.o * o // fully specified and imported
}
}
An object has exactly one instance (you can not call new MyObject). You can have multiple instances of a class.
Object serves the same (and some additional) purposes as the static methods and fields in Java.
As has been explained by many, object defines a singleton instance. The one thing in the answers here that I believe is left out is that object serves several purposes.
It can be the companion object to a class/trait, containing what might be considered static methods or convenience methods.
It can act much like a module, containing related/subsidiary types and definitions, etc.
It can implement an interface by extending a class or one or more traits.
It can represent a case of a sealed trait that contains no data. In this respect, it's often considered more correct than a case class with no parameters. The special case of a sealed trait with only case object implementors is more or less the Scala version of an enum.
It can act as evidence for implicit-driven logic.
It introduces a singleton type.
It's a very powerful and general construct. What can be very confusing to Scala beginners is that the same construct can have vastly different uses. And an object can serve many of these different uses all at once, which can be even more confusing.
Defining an object in Scala is like defining a class in Java that has only static methods. However, in Scala an object can extend another superclass, implement interfaces, and be passed around as though it were an instance of a class. (So it's like the static methods on a class but better).
The formal difference -
you can not provide constructor parameters for Objects
Object is not a type - you may not create an instance with new operator. But it can have fields, methods, extend a superclass and mix in traits.
The difference in usage:
Scala doesn't have static methods or fields. Instead you should use object. You can use it with or without related class. In 1st case it's called a companion object. You have to:
use the same name for both class and object
put them in the same source file.
To create a program you should use main method in object, not in class.
object Hello {
def main(args: Array[String]) {
println("Hello, World!")
}
}
You also may use it as you use singleton object in java.
In scala, there is no static concept. So scala creates a singleton object to provide entry point for your program execution.
If you don't create singleton object, your code will compile successfully but will not produce any output. Methods declared inside Singleton Object are accessible globally. A singleton object can extend classes and traits.
Scala Singleton Object Example
object Singleton{
def main(args:Array[String]){
SingletonObject.hello() // No need to create object.
}
}
object SingletonObject{
def hello(){
println("Hello, This is Singleton Object")
}
}
Output:
Hello, This is Singleton Object
In scala, when you have a class with same name as singleton object, it is called companion class and the singleton object is called companion object.
The companion class and its companion object both must be defined in the same source file.
Scala Companion Object Example
class ComapanionClass{
def hello(){
println("Hello, this is Companion Class.")
}
}
object CompanoinObject{
def main(args:Array[String]){
new ComapanionClass().hello()
println("And this is Companion Object.")
}
}
Output:
Hello, this is Companion Class.
And this is Companion Object.
In scala, a class can contain:
1. Data member
2. Member method
3. Constructor Block
4. Nested class
5. Super class information etc.
You must initialize all instance variables in the class. There is no default scope. If you don't specify access scope, it is public. There must be an object in which main method is defined. It provides starting point for your program. Here, we have created an example of class.
Scala Sample Example of Class
class Student{
var id:Int = 0; // All fields must be initialized
var name:String = null;
}
object MainObject{
def main(args:Array[String]){
var s = new Student() // Creating an object
println(s.id+" "+s.name);
}
}
I am sorry, I am too late but I hope it will help you.
The object keyword creates a new singleton type, which is like a class that only has a single named instance. If you’re familiar with Java, declaring an object in Scala is a lot like creating a new instance of an anonymous class.
Scala has no equivalent to Java’s static keyword, and an object is often used in Scala where you might use a class with static members in Java.
Object is a class but it already has(is) an instance, so you can not call new ObjectName. On the other hand, Class is just type and it can be an instance by calling new ClassName().
A class is just like any other class in other languages. You define class just like any other language with some syntax difference.
class Person(val name: String)
val me = new Person("My name")
However, object is a class with single object only. This makes it interesting as it can be used to create static members of a class using companion object. This companion object has access to private members of the class definition and it has the same name as the class you're defining.
class Person(var name: String) {
import Person._
def hi(): String = sayHello(name)
}
object Person {
private def sayHello(name: String): String = "Hello " + name
}
val me = new Person("My name")
me.hi()
Also, noteworthy point is that object class is lazily created which is another important point. So, these are not instantiated unless they are needed in our code.
If you're defining connection creation for JDBC, you can create them inside object to avoid duplication just like we do in Java with singleton objects.
Scala class same as Java Class but scala not gives you any entry method in class, like main method in java. The main method associated with object keyword. You can think of the object keyword as creating a singleton object of a class that is defined implicitly.
more information check this article
class and object keyword in scala programming
The object is similar to the static class in Java to some extend, the static characteristic means the static class need not to create an object when putting to the JVM, it can be used by it's class name directly and the same instance(same data state) is shared wherever it is used.
If you are coming from java background the concept of class in scala is kind of similar to Java, but class in scala cant contain static members.
Objects in scala are singleton type you call methods inside it using object name, in scala object is a keyword and in java object is a instance of class