Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any Scala feature that allows you to call a method whose name is stored in a string?

Tags:

Assuming you have a string containing the name of a method, an object that supports that method and some arguments, is there some language feature that allows you to call that dynamically?

Kind of like Ruby's send parameter.

like image 947
Geo Avatar asked Jan 13 '10 21:01

Geo


People also ask

How do you call a method in Scala?

Method Invocation is a technique that demonstrates different syntax in which we dynamically call methods of a class with an object. There should not be any space between the invocation object/target and the dot(.) nor a space between the dot and method name.

What is string * in Scala?

Scala string is an immutable object that means the object cannot be modified. Each element of a string is associated with an index number. The first character is associated with the number 0, the second with the number 1, etc. Class java. lang.

What does => mean in Scala?

=> is the "function arrow". It is used both in function type signatures as well as anonymous function terms. () => Unit is a shorthand for Function0[Unit] , which is the type of functions which take no arguments and return nothing useful (like void in other languages).

What do you call a function defined in a block in Scala?

A method is a function defined in a class and available from any instance of the class. The standard way to invoke methods in Scala (as in Java and Ruby) is with infix dot notation, where the method name is prefixed by the name of its instance and the dot ( . )


1 Answers

You can do this with reflection in Java:

class A {   def cat(s1: String, s2: String) = s1 + " " + s2 } val a = new A val hi = "Hello" val all = "World" val method = a.getClass.getMethod("cat",hi.getClass,all.getClass) method.invoke(a,hi,all) 

And if you want it to be easy in Scala you can make a class that does this for you, plus an implicit for conversion:

case class Caller[T>:Null<:AnyRef](klass:T) {   def call(methodName:String,args:AnyRef*):AnyRef = {     def argtypes = args.map(_.getClass)     def method = klass.getClass.getMethod(methodName, argtypes: _*)     method.invoke(klass,args: _*)   } } implicit def anyref2callable[T>:Null<:AnyRef](klass:T):Caller[T] = new Caller(klass) a call ("cat","Hi","there") 

Doing this sort of thing converts compile-time errors into runtime errors, however (i.e. it essentially circumvents the type system), so use with caution.

(Edit: and see the use of NameTransformer in the link above--adding that will help if you try to use operators.)

like image 122
Rex Kerr Avatar answered Sep 21 '22 01:09

Rex Kerr