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().
Related
Is there a way to invoke a function by default before any other function in a class is called?
I do not want to use frameworks and want to implement in pure Scala.
What I wanted to do is have some function in a class which checks if a user has access to the called method when a method of the same class is called.
This is done in a straightforward way with a private constructor, custom apply and companion object.
case class Foo private (bar: Bar){
def methYouWantToCall: Unit = ???
}
object Foo {
def apply(bar: Bar): Foo = {
val foo = new Foo(bar)
foo.methYouWantToCall
foo
}
}
Hence methYouWantToCall should be sideffecting function with Unit return type.
As you use scala, there are plenty of means of avoiding such ones.
I'm running into
error: not found: value defineParser
[scalac-2.11] def this(format: String) = this(format, defineParser(format))
when I try to call a method in the this method of a class in order to dynamically return a parser depending on the format.
The class entire structure looks like so:
class TimestampConversion(format: String, parser: DSVTimestampFormatter) extends ObjectConversion[Any] with FormattedConversion[DSVTimestampFormatter] {
def defineParser(format: String): DSVTimestampFormatter = {
// hidden implementation details
}
def this(format: String) = this(format, defineParser(format))
}
And this fails on compiling this class. Why am I not able to invoke the defineParser method? It's well defined there.
It's OK to define a secondary constructor, but it's slightly more idiomatic to add apply factory methods to the companion object instead.
It's also possible to add a default arg for the parameter in the primary constructor, where it's more obvious what the scope is:
class C(format: String)(parser: Parser = C.defineParser(format))
object C { private def defineParser(format: String): Parser = ??? }
Here is the spec language (section 5.3.1) saying that the scope for your this invocation is not "inside the braces of the class definition":
The signature and the self constructor invocation of a constructor
definition are type-checked and evaluated in the scope which is in
effect at the point of the enclosing class definition, augmented by
any type parameters of the enclosing class and by any early
definitions of the enclosing template. The rest of the constructor
expression is type-checked and evaluated as a function body in the
current class.
This question is somewhat hard to summarize. Following code block shows what I want to do.
I have a base class like this:
`class Base {
def methA:String="ook"
def methB:Int=1
}
Also I have a derived class, where I want each subclass method to call the super class method twice, compare the results and throw an exception on mismatch (this is for a test scenario).
But if I write
class Derived extends Base {
private def callDoublyAndCompare[T](fun:()=>T) : T = {
val fst=fun()
val snd=fun()
if(fst!=snd) throw new RuntimeException(s"Mismatch fst=$fst != snd=$snd")
snd
}
override def methB:Int={
callDoublyAndCompare(() => super[Derived].methB)
}
}
Then this will not compile. The only way out of this problem sofar has been to extract a method in class Derived which only calls the superclass' methB and to call this from the lambda call.
Is there a better way?
I understood you want to call super call method. Hope below is what you want.
You can call that as below with the key word super only
(new Derived).methB . This will call super call method in callDoublyAndCompare twice as per your code .
class Derived extends Base {
private def callDoublyAndCompare[T](fun:()=>T) : T = {
val fst=fun()
val snd=fun()
if(fst!=snd) throw new RuntimeException(s"Mismatch fst=$fst != snd=$snd")
snd
}
override def methB:Int={
callDoublyAndCompare(() => super.methB) //kept only super
}
}
The original example was not fully complete insofar as the Derived class was defined as inner class of another scala class.
After I moved out this inner class to the top level, the example from Praveen above suddenly worked.
I get to know about the Invoke operator that,
a() is equivalent to a.invoke()
Is there anything more regarding Invoke operator than please explain. Also, I did not get any example of Invoke operator overloading.
Is Invoke operator overloading possible? If possible then can anyone please explain about the Invoke operator overloading with an example? I did not get anything regarding this.
Thanks in advance.
Yes, you can overload invoke. Here's an example:
class Greeter(val greeting: String) {
operator fun invoke(target: String) = println("$greeting $target!")
}
val hello = Greeter("Hello")
hello("world") // Prints "Hello world!"
In addition to what #holi-java said, overriding invoke is useful for any class where there is a clear action, optionally taking parameters. It's also great as an extension function to Java library classes with such a method.
For example, say you have the following Java class
public class ThingParser {
public Thing parse(File file) {
// Parse the file
}
}
You can then define an extension on ThingParser from Kotlin like so:
operator fun ThingParser.invoke(file: File) = parse(file)
And use it like so
val parser = ThingParser()
val file = File("path/to/file")
val thing = parser(file) // Calls ThingParser.invoke extension function
The most way to use a invoke operator is use it as a Factory Method, for example:
// v--- call the invoke(String) operator
val data1 = Data("1")
// v--- call the invoke() operator
val default = Data()
// v-- call the constructor
val data2 = Data(2)
This is because the companion object is a special object in Kotlin. Indeed, the code Data("1") above is translated to the code as below:
val factory:Data.Companion = Data
// v-- the invoke operator is used here
val data1:Data = factory.invoke("1")
class Data(val value: Int) {
companion object {
const val DEFAULT =-1
// v--- factory method
operator fun invoke(value: String): Data = Data(value.toInt())
// v--- overloading invoke operator
operator fun invoke(): Data = Data(DEFAULT)
}
}
Operator Function invoke()
Kotlin provides an interesting function called invoke, which is an operator function. Specifying an invoke operator on a class allows it to be called on any instances of the class without a method name.
Let’s see this in action:
class Greeter(val greeting: String) {
operator fun invoke(name: String) {
println("$greeting $name")
}
}
fun main(args: Array<String>) {
val greeter = Greeter(greeting = "Welcome")
greeter(name = "Kotlin")
//this calls the invoke function which takes String as a parameter
}
A few things to note about invoke() here. It:
Is an operator function.
Can take parameters.
Can be overloaded.
Is being called on the instance of a Greeter class without method name.
In addition to the other answers:
It's possible to define a class extending an anonymous function.
class SpecialFunction : () -> Unit {}
In such case, the operator invoke is already defined, so it needs to be overriden:
class MyFunction : () -> Unit {
override fun invoke() { println("Hi Mom") }
}
One more thing about syntax repercussions:
If such "functor" is called right after constructing it, you end up with double parentheses:
MyFunction()()
And, if such functor returns another functor, you may see some obscurities like
MyFunction()()()()()...
perhaps including parameters. This will not surprise anyone coming from the JavaScript world, though.
If you have some Python background,
you can think invoke in Kotlin as __call__ in Python.
By using this, you can "call" your object as if it's a function.
One difference is: you can overload invoke, but there is no official way to overload methods in Python.
How to call such a scala function?
def f(v: Void): Unit = {println(1)}
I haven't found a value of Void type in Scala yet.
I believe using Void/null in Java is similar to using Unit/() in Scala. Consider this:
abstract class Fun<A> {
abstract public A apply();
}
class IntFun extends Fun<Integer> {
public Integer apply() { return 0; }
}
public static <A> A m(Fun<A> x) { return x.apply(); }
Now that we defined generic method m we also want to use it for classes where apply is only useful for its side effects (i.e. we need to return something that clearly indicates it's useless). void doesn't work as it breaks Fun<A> contract. We need a class with only one value which means "drop return value", and it's Void and null:
class VoidFun extends Fun<Void> {
public Void apply() { /* side effects here */ return null; }
}
So now we can use m with VoidFun.
In Scala usage of null is discouraged and Unit is used instead (it has only one value ()), so I believe the method you mentioned was intended to be called from Java. To be compatible with Java Scala has null which is the only instance of a class Null. Which in turn is a subtype of any reference class, so you can assign null to any reference class variable. So the pattern Void/null works in Scala too.
Void, or more specifically, java.lang.Void, has the following in the documentation:
The Void class is an uninstantiable placeholder class to hold a
reference to the Class object representing the Java keyword void.
In Scala, there's no keyword void, so the Void type is essentially useless in Scala. The closest thing is either a function with no parameters, i.e. def f: Unit = {println(1)} which you can call using f or f(), or the Unit type for functions that don't return anything, as in your example.