这取决于您如何严格定义可接受的输入字符串。该物体是否总是被称为MyObj
?该方法应该总是被称为getX
?它应该总是1方法还是可以是多个?
对于更一般的情况,您可以尝试从AST中提取所有方法名称并生成对每个方法的调用。下面的代码将调用每一个方法(和返回的最后一个结果),其采用0参数,而不是一个构造,在一些对象,不考虑继承到:
def eval(string: String): Any = {
val toolbox = currentMirror.mkToolBox()
val tree = toolbox.parse(string)
//oName is the name of the object
//defs is the list of all method definitions
val ModuleDef(_,oName,Template(_,_,defs)) = tree
//only generate calls for non-constructor, zero-arg methods
val defCalls = defs.collect{
case DefDef(_,name,_,params,_,_)
if name != termNames.CONSTRUCTOR && params.flatten.isEmpty => q"$oName.$name"
}
//put the method calls after the object definition
val block = tree :: defCalls
toolbox.eval(q"..$block")
}
,并用它:
scala> eval("""object MyObj { def bar() = println("bar"); def foo(a: String) = println(a); def getX = "x" }""")
bar
res60: Any = x
尝试quasiquote? –