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

Geo picture Geo · Jan 13, 2010 · Viewed 18.3k times · Source

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.

Answer

Rex Kerr picture Rex Kerr · Jan 13, 2010

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.)