I've made a class in CoffeeScript and I'd like to overwrite the toString() function; here's my code:
class MenuController
constructor: () ->
'constructor'
toString: () ->
'MenuController'
console.log MenuController.toString()
However toString() returns:
function MenuController() {
'constructor';
}
And not MenuController. What am I doing wrong?
You defined toString as a class method. So, you can call it as:
menuController = new MenuController()
menuController.toString()
If a static method is really what you want, then you should use the following syntax:
class MenuController
#toString: ->
'MenuController'
Then, you'll be able to call it like:
MenuController.toString()
But, it will no longer be a class method, so
(new MenuController()).toString()
won't call your toString method.
Related
I have to write scheduler that callbacks a function after processing. I can register the class name and method name as strings and have to callback it in future.
How can I call a function with class name and method name in Scala.
Same with java, use reflect.
package tst
class A {
def fun(a:String) = print(a)
}
object B extends App {
val classA = Class.forName("tst.A")
val method = classA.getDeclaredMethod("fun", classOf[String])
method.invoke(classA.newInstance(), "hello world")
}
Let's begin with class structure
The class structure
Base abstract class
abstract class BaseCass {
def someFunction() : Any
//Here is the place where someFunction is called
startUpMethod = {
someFunction()
}
}
Base implemetation
import Utility._
class BaseImpelmentation {
//These parameters are not passed into method calls
implicit object ParameterOne = ParameterOne
implicit object ParameterSecond = ParameterSecond
implicit object ParameterThird = ParameterThird
def someFunction() : Any = {
functionWithImplicitOne();
functionWithImplicitSecond();
functionWithImplicitThird();
}
}
Class with implicit functions
class Utility {
//here all function with implicit are defined.
}
The algorithm is
someFunction is called at class initialization e.g. it called after constructor, but before any other methods in class
someFunction overrided in BaseImpelmentation
BaseImpelmentation imports function with implicit parameters from Utility class.
The problem
When someFunction is called in BaseClass implicit parameters from BaseImpelmentation are not used. So I have to place them in BaseCass. But in that case I place a piece of implementation to abstract class which is not very good.
Is it possible to place implicit parametrs into BaseImpelmentation but do not pass them as usual parameters?
If someFunction is only called when the class is fully constructed then this should work; the call to functionWithImplicitOne() in BaseImpelmentation[sic] will use ParameterOne, because it is in scope where the method is called. Your problem is something else. What is the actual error message?
When I run below code the apply method is not being called :
Java :
public class Driver {
public static void main(String args[]){
new parallel.TestData();
}
}
Scala :
package parallel
class TestData {
def apply() = {
println("in apply method ")
}
}
If I use :
new parallel.TestData().apply();
then the apply method is called correctly but should the apply() method not be implicitly invoked from above code ? Is the apply method not implemented correctly ?
In Scala, there is a difference between a constructor and the apply method. It seems that you expect the apply method to act like a constructor. However, the constructor is a method named def this(...). Your are hence not defining a constructor.
The apply method can be called by using a name just like any other method (.apply()) or by using parantheses (()). After having created a new instance of your class, you still need to call the apply method.
You can thus either create a new instance of your class and call apply:
new parallel.TestData()()
// ^ ^---- apply method
// |------- constructor
Or you can implement an object instead of a class:
object TestData {
def apply() = {
println("in apply method ")
}
}
parallel.TestData()
Update: When calling Scala code from Java, you would have to stick to the first method. As Java does not add syntactic sugar for the apply method, you are left with the option of an explicit call: new parallel.TestData().apply().
I have two coffeescript classes something like this. In the base view model I have a method that I want to override in the child that inherits from the base view model.
class exports.BaseViewModel
constructor: () ->
someBaseMethod: =>
console.log "I'm doing the base stuff"
class ChildViewModel extends BaseViewModel
constructor: () ->
someBaseMethod: =>
#doSomethingFirst()
super #someBaseMethod()
This isn't working as is because the line super #someBaseMethod() calls itself creating an infinite loop.
Is it possible to achieve what I want here?
Yes, call super just like it was a function (it represents a reference to the superclass version of the method you're in):
class ChildViewModel extends BaseViewModel
constructor: ->
someBaseMethod: =>
#doSomethingFirst()
super()
Using Groovy's package name convention, I can intercept Groovy method calls to a Java method like so:
package groovy.runtime.metaclass.org.myGang.myPackage
class FooMetaClass extends groovy.lang.DelegatingMetaClass
{
FooMetaClass(MetaClass delegate)
{
super(delegate);
}
public Object getProperty(Object a, String key)
{
return a.someMethod(key)
}
}
This works fine if I really create an object of class Foo:
def myFoo = new Foo()
def fooProperty = myFoo.bar // metaclass invokes myFoo.someMethod("bar")
However what if Foo is an interface, and I want to intercept method calls to any implementation of it?
def myFoo = FooFactory.create() // I don't know what class this will be
fooProperty = myFoo.bar
Is there a way to achieve this without having a DelegatingMetaClass for every known implementation of the Interface?
You can create a class named "groovy.runtime.metaclass.CustomMetaClassCreationHandle" to globally handle metaclass creation process.
Inside this class, you can override this method:
protected MetaClass createNormalMetaClass(Class theClass, MetaClassRegistry registry) {
// if theClass instanceof Foo, return your special metaclass
// else return super.createNormalMetaClass(theClass, registry)
}