Scala call single parameter method using space in anonymous class body - scala

In scala, how can I call a single parameter method using space in the body of the anonymous class?
add "Answer3" below is not working
trait Question {
def add(answer:String):Unit = {
println("Received the answer=" + answer)
}
}
object Test {
val question:Question = new Question {
this add "Answer1" // working
add("Answer2") // working
add "Answer3" // NOT working, why? -> error: ';' expected but string literal found.
}
}

You're trying to mix two different, and conflicting, convenience syntax options.
instance.method(argument)
... can be expressed as ...
instance method argument
... and, if the method() takes no argument then that can also be expressed with spaces, but the parser needs a little help.
instance method;
On a separate track, if the instance is this then that can be dropped.
method(argument)
But you can't drop the parentheses because the parser tries to interpret that as instance method and fails.

Related

Spark Scala Register UDF - Why I need to pass underscore (_) at the end of function

I have created an UDF in Scala and when I was trying to register this UDF with just function name it was showing me error.
Not Working
def IPConvertUDF = spark.udf.register("IPConvertUDF", IPConvert)
Error
error: missing argument list for method IPConvert
Unapplied methods are only converted to functions when a function type is expected.
You can make this conversion explicit by writing `IPConvert _` or `IPConvert(_)` instead of `IPConvert`.
def IPConvertUDF = spark.udf.register("IPConvertUDF", IPConvert)
And so I added extra _ after method name and it worked.
Works perfectly
def IPConvertUDF = spark.udf.register("IPConvertUDF", IPConvert _)
Would someone be able to explain be what is the meaning of extra _ after the method name?
Well the short answer is, you are trying to pass a method where a function is expected as an argument. Methods are not functions.
Let's dig a bit deeper.
Lets try with simple add function first
val add:(Int,Int) => Int = (val1,val2) => val1+val2
spark.udf.register("add",add)
The above code compiled without any error. The reason is add is a function.
Now lets try the same add as a method
def add(val1:Int,val2:Int): Int ={
val1+val2
}
spark.udf.register("add",add)
Now you get an error saying error: missing argument list for method add.
As I mentioned, register(..) is expecting function and methods cannot be passed as arguments.
_ is a shorthand for partially applied function.In other words , add method is converted into partially applied function and that's the reason the error has disappeared.
spark.udf.register("add",add _)

Scala - Method Parameters - def function: Row => Message = { row => {

Coming from Java background trying to understand this Scala code:
def function: Row => Message = {
row => {
// code
// code
}
}
As I understand we pass a function that returns type Message? And then we actually implement row? Why first Row is capital and second is not?
Thanks.
Let's break it down.
def function
Declare a method named function that has no inputs.
:Row => Message
The return type is a function that take a Row as input and returns a Message
= row => {...}
Define and anonymous function with a single input named row. This is the function that is returned (in Scala the last thing in a block is returned so you don't need to use the return keyword). Scala is able to figure out what the input and output types of this function should be because they have to match the return type you declared for the method.
As I understand we pass a function that returns type Message?
No. Nothing is being passed. The method function doesn't have any parameters, it doesn't take any arguments, so you can't pass any.
And then we actually implement row?
No. Nothing is being implemented. There are no abstract members or abstract interfaces here to implement.
Why first Row is capital and second is not?
It doesn't have to be. It's just a convention. Types are usually written in PascalCase, parameters, fields, and methods in camelCase. (Actually, it's the exact same thing in Java.)
A rough Java equivalent would look something like this:
java.util.Function<Row, Message> function() {
return row -> {
// code
// code
};
}
As you can see, there really isn't much difference between the two.
The return type is a function that takes type Row and returns Message. There should be some higher level implementation of that function.
Check this link, it will help you understand:
https://www.safaribooksonline.com/library/view/scala-cookbook/9781449340292/ch09s08.html
Not quite.
def means that you are defining a method. In this case it takes no argument and its return type is Row => Message.
So the function method you are defining returns a function that takes a Row and returns a Message.

Scala code - Strange behaviour [duplicate]

This question already has an answer here:
Difference between function with parentheses and without [duplicate]
(1 answer)
Closed 6 years ago.
I was learning about scala methods and I created two code examples which are somewhat similar in nature, but confused on calling them.
Method #1
def someTestMethod = {
println("Inside a test method")
}
This resorts to a Unit type since it does not return anything.
Method #2
def anotherTestMethod() = {
println("Inside a test method")
}
This resorts to Unit as well, but with a curly brace () added.
What is the difference between the two methods, notice that if I call the first method like someTestMethod(), the scala shell/compiler says
error: Unit does not take parameters, but works well if I call like someTestMethod without the braces.
Also, the second method seems fool proof, in the sense that it can be called either way anotherTestMethod or anotherTestMethod(), why is it so?
When you don't want to pass any parameter to the method, use the first one.
If you want to pass some pass parameters, use the second one with brackets and pass some parameters and use it inside method.
For example:
def someTestMethod1(count : Int) = {
println("Inside a test method"+count)
}
someTestMethod1(10)

Verifying mocked object method calls with default arguments

Suppose I have this class:
class Defaults {
def doSomething(regular: String, default: Option[String] = None) = {
println(s"Doing something: $regular, $default")
}
}
I want to check that some other class invokes doSomething() method on Defaults instance without passing second argument:
defaults.doSomething("abcd") // second argument is None implicitly
However, mocking Defaults class does not work correctly. Because default values for method arguments are compiled as hidden methods in the same class, mock[Defaults] returns an object in which these hidden methods return null instead of None, so this test fails:
class Test extends FreeSpec with ShouldMatchers with MockitoSugar {
"Defaults" - {
"should be called with default argument" in {
val d = mock[Defaults]
d.doSomething("abcd")
verify(d).doSomething("abcd", None)
}
}
}
The error:
Argument(s) are different! Wanted:
defaults.doSomething("abcd", None);
-> at defaults.Test$$anonfun$1$$anonfun$apply$mcV$sp$1.apply$mcV$sp(Test.scala:14)
Actual invocation has different arguments:
defaults.doSomething("abcd", null);
-> at defaults.Test$$anonfun$1$$anonfun$apply$mcV$sp$1.apply$mcV$sp(Test.scala:12)
The reason of this is clear, but is there a sensible workaround? The only one I see is to use spy() instead of mock(), but my mocked class contains a lot of methods which I will have to mock explicitly in this case, and I don't want it.
This is related with how the Scala compiler implements this as a Java class, remember that Scala runs on the JVM, so everything needs to be transformed to something that looks like Java
In this particular case, what the compiler does is to create a series of hidden methods which will be called something like methodName$default$number where number is the position of the argument this method is representing, then, the compiler will check every time we call this method and if we don’t provide a value for such parameter, it will insert a call to the $default$ method in its place, an example of the “compiled” version would be something like this (note that this is not exactly what the compiler does, but it works for educational purposes)
class Foo {
def bar(noDefault: String, default: String = "default value"): String
}
val aMock = mock[Foo]
aMock.bar("I'm not gonna pass the second argument")
The last line would be compiled as
aMock.bar("I'm not gonna pass the second argument", aMock.bar$default$1)
Now, because we are making the call to bar$default$1 on a mock, and the default behaviour of Mockito is to return null for anything that hasn’t been stubbed, then what ends up executing is something like
aMock.iHaveSomeDefaultArguments("I'm not gonna pass the second argument", null)
Which is exactly what the error is telling…
In order to solve this some changes have to be made so mockito actually calls the real $default$ methods and so the replacement is done correctly
This work has been done in mockito-scala, so by migrating to that library you'll get a solution for this and many other problems that can be found when mockito is used in Scala
Disclaimer: I'm a developer of mockito-scala

When is a scala partial function not a partial function?

While creating a map of String to partial functions I ran into unexpected behavior. When I create a partial function as a map element it works fine. When I allocate to a val it invokes instead. Trying to invoke the check generates an error. Is this expected? Am I doing something dumb? Comment out the check() to see the invocation. I am using scala 2.7.7
def PartialFunctionProblem() = {
def dream()() = {
println("~Dream~");
new Exception().printStackTrace()
}
val map = scala.collection.mutable.HashMap[String,()=>Unit]()
map("dream") = dream() // partial function
map("dream")() // invokes as expected
val check = dream() // unexpected invocation
check() // error: check of type Unit does not take parameters
}
For convenience, Scala lets you omit empty parens when calling a method, but it's clever enough to see that the expected type in the first case is ()=>Unit, so it doesn't remove all the parens for you; instead, it converts the method into a function for you.
In the val check case, however, it looks just like a function call result getting assigned to a variable. In fact, all three of these do the exact same thing:
val check = dream
val check = dream()
val check = dream()()
If you want to turn the method into a function, you place _ after the method in place of the argument list(s). Thus,
val check = dream() _
will do what you want.
Well, the problem is that you got it all wrong. :-)
Here are some conceptual mistakes:
def dream()() = {
println("~Dream~");
new Exception().printStackTrace()
}
This is not a partial function. This is a curried method with two empty parameter lists which returns Unit.
val map = scala.collection.mutable.HashMap[String,()=>Unit]()
The type of the values in this map is not partial function, but function. Specifically, Function0[Unit]. A partial function would have type PartialFunction[T, R].
map("dream") = dream() // partial function
What happens here is that Scala converts the partially applied method into a function. This is not a simple assignment. Scala does the conversion because the type inferencer can guess the correct type.
val check = dream() // unexpected invocation
Here there's no expected type to help the type inferencer. However, empty parameter lists can be ommitted, so this is just a method call.