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.
Related
Is it possible to create a callable object in Kotlin and/or Swift?
I have many objects that have just one method execute. The object is basically used as a closure. Some dependencies are captured during object construction. Some arguments are passed when the execute method is called.
The reason I’m not using plain functions is the classes implement interfaces and type checking is much more helpful though out the program.
You can overload the invoke operator:
class Callable(val prop: String) {
operator fun invoke(para : String) {
println("Invoke: $prop $para")
}
}
fun main() {
val c = Callable("prop")
c("para")
}
I am trying to understand Anonymous subclass in Scala. I have written the below code:
package com.sudipta.practice.chapter8
class Person(val name: String) {
def printMyName = println("Name: " + name)
}
class AnonymousSubclass(val name: String) {
val anonymousSubclass = new Person(name){
def sayHello = "Hello, " + name
def sayBye = "Bye, " + name
override def printMyName = println("My name is: " + name)
}
}
object testPerson extends App {
def printAnonDetails (myObject: AnonymousSubclass) = {
myObject.anonymousSubclass.printMyName
}
val personObject = new Person("Sudipta")
personObject.printMyName
val anonObject = new AnonymousSubclass("Sudipta")
printAnonDetails(anonObject)
}
But what I am not able to understand what are the usages/advantages of Anonymous Subclass in Scala. If you have any points, please share here. Thanks.
Regadrs,
Sudipta
The use of anonymous subclasses in Scala is no different than the use of anonymous subclasses in Java. The most common use in Java is probably in the observer pattern as shown in the first link.
The example directly translates to Scala:
button.addActionListener(new ActionListener() {
def actionPerformed(e: ActionEvent) {
// do something.
}
});
However, in Scala you would probably rather use an anonymous function for that (if the library allows you to):
button.addActionListener(e => /* do something */)
In Scala you might use anonymous subclasses in this case, if:
Your client requires you to extend a given interface
You register for multiple events at a time (for example a java.awt.MouseListener)
These are of course only examples. In any location where not naming a class makes sense to you, you may use an anonymous (sub)class.
Anonymous classes in Scala, Java, and pretty much any other language that supports them are useful in cases where you need to pass an instance of some interface or base class as an argument to a function, and you will never need to use the same implementation anywhere else in your code.
Note that only members and methods that are defined by the interface or base class that your anonymous class implements/extends will be visible outside the anonymous class. In your example, this means that your sayHello and sayBye methods can only be called by anonymous's overrided printMyName (if this method need to call them), or the anonymous class's constructor, since nobody else outside the anonymous class will be able to know about them, as they are Not declared in the base class (Person).
I've got a class from a library (specifically, com.twitter.finagle.mdns.MDNSResolver). I'd like to extend the class (I want it to return a Future[Set], rather than a Try[Group]).
I know, of course, that I could sub-class it and add my method there. However, I'm trying to learn Scala as I go, and this seems like an opportunity to try something new.
The reason I think this might be possible is the behavior of JavaConverters. The following code:
class Test {
var lst:Buffer[Nothing] = (new java.util.ArrayList()).asScala
}
does not compile, because there is no asScala method on Java's ArrayList. But if I import some new definitions:
class Test {
import collection.JavaConverters._
var lst:Buffer[Nothing] = (new java.util.ArrayList()).asScala
}
then suddenly there is an asScala method. So that looks like the ArrayList class is being extended transparently.
Am I understanding the behavior of JavaConverters correctly? Can I (and should I) duplicate that methodology?
Scala supports something called implicit conversions. Look at the following:
val x: Int = 1
val y: String = x
The second assignment does not work, because String is expected, but Int is found. However, if you add the following into scope (just into scope, can come from anywhere), it works:
implicit def int2String(x: Int): String = "asdf"
Note that the name of the method does not matter.
So what usually is done, is called the pimp-my-library-pattern:
class BetterFoo(x: Foo) {
def coolMethod() = { ... }
}
implicit def foo2Better(x: Foo) = new BetterFoo(x)
That allows you to call coolMethod on Foo. This is used so often, that since Scala 2.10, you can write:
implicit class BetterFoo(x: Foo) {
def coolMethod() = { ... }
}
which does the same thing but is obviously shorter and nicer.
So you can do:
implicit class MyMDNSResolver(x: com.twitter.finagle.mdns.MDNSResolver) = {
def awesomeMethod = { ... }
}
And you'll be able to call awesomeMethod on any MDNSResolver, if MyMDNSResolver is in scope.
This is achieved using implicit conversions; this feature allows you to automatically convert one type to another when a method that's not recognised is called.
The pattern you're describing in particular is referred to as "enrich my library", after an article Martin Odersky wrote in 2006. It's still an okay introduction to what you want to do: http://www.artima.com/weblogs/viewpost.jsp?thread=179766
The way to do this is with an implicit conversion. These can be used to define views, and their use to enrich an existing library is called "pimp my library".
I'm not sure if you need to write a conversion from Try[Group] to Future[Set], or you can write one from Try to Future and another from Group to Set, and have them compose.
The Java Mocking framework Mockito has a utility class called ArgumentCaptor that accumulates a list of values as a method under verification is invoked multiple times.
Does ScalaMock have a similar mechanism?
There's an under the hood mechanism that does this in the preview release of ScalaMock3, but it's not currently exposed to client code.
What's your use case for this?
You might be able to achieve what you need by using where or onCall documented here (under the "Predicate matching" and "Return Value" headings respectively).
In Specs2 you can use the following:
myMock.myFunction(argument) answers(
passedArgument => "something with"+passedArgument
)
This maps to Mockito's ArgumentCaptor under the hood.
According to the Mockito documentation, you can use specs2 matchers directly, e.g.
val myArgumentMatcher: PartialFunction[ArgumentType, MatchResult[_]] = {
case argument => argument mustEqual expectedValue
}
there was one(myMock).myFunction(beLike(myArgumentMatcher))
The cool thing about this solution is that the partial function allows for really great flexibility. You can pattern match on your argument, etc. Of course, if you really just need to compare the argument value, then there's no need for the partial function, you can just do
there was one(myMock).myFunction(==_(expectedValue))
Another option is to implement your own argument captor by extending the existing matchers. Something of the kind should do the trick (For scalamock 3) :
trait TestMatchers extends Matchers {
case class ArgumentCaptor[T]() {
var valueCaptured: Option[T] = None
}
class MatchAnyWithCaptor[T](captor: ArgumentCaptor[T]) extends MatchAny {
override def equals(that: Any): Boolean = {
captor.valueCaptured = Some(that.asInstanceOf[T])
super.equals(that)
}
}
def capture[T](captor: ArgumentCaptor[T]) = new MatchAnyWithCaptor[T](captor)
}
You can use this new matcher by adding that trait to your test class
val captor = new ArgumentCaptor[MyClass]
(obj1.method(_: MyClass)).expects(capture(captor)).returns(something)
println(captor.capturedValue)
Use ArgumentCapture:
val subject = new ClassUnderTest(mockCollaborator)
// Create the argumentCapture
val argumentCapture = new ArgumentCapture[ArgumentClazz]
// Call the method under test
subject.methodUnderTest(methodParam)
// Verifications
there was one (mockCollaborator).someMethod(argumentCapture)
val argument = argumentCapture.value
argument.getSomething mustEqual methodParam
A minimized example is the following:
object Main extends App {
def f = {
def giveMeBigDecimal(x: String) = BigDecimal(x)
def giveMeBigDecimal(x: Double) = BigDecimal(x)
(giveMeBigDecimal("1.0"), giveMeBigDecimal(1.0))
}
}
Scala 2.9.2 compiler keep saying me that method giveMeBigDecimal is defined twice
I know how can I workaround this, but curious why such limitation exists.
It's a Scala's implementation detail which (unfortunately) made its way to the spec. Scala implements local methods as variables with closure type and it isn't allowed to have two variables with the same name in the same method.