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 dinamically? Kind of like Ruby's send
.
views:
155answers:
3Yes. It's called reflection. Here's a link to one way However you should remember that Scala is not a dynamic language, and may not be able to easily do some things that scripting languages can do. You're probably better doing a match on the string, and then calling the right method.
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.)
Liftweb framework relies on reflection very much and has a good set of tools developed to ease this kind of tasks. See ClassHelpers.scala source for inspiration