如何在评估之前使用反射来拦截表达式?

How to use reflection to intercept an expression prior to evaluation?

我希望在计算之前使用 R 的反射功能拦截正在计算的当前表达式。

例如,要创建一些语法糖,给出以下内容:

> Server <- setRefClass("Server",
>   methods = list(
>       handler = function(expr) submitExpressionToRemoteServer(expr)
>   )
> )
> server <- Server()
> server$foo$bar$baz    #... should be map to...    server$handler("foo$bar$baz")

我希望表达式 server$foo$bar$bazserver$handler 方法拦截并映射到 server$handler("foo$bar$baz")

请注意,即使未定义 server$foo,我也希望此调用成功:我只对 表达式本身感兴趣 (因此我可以使用表达式),而不是它计算为有效的本地对象。

这可能吗?

我认为用 R 中的参考 类 (R5) 对象重新定义 $ 行为是不可能的。但是,您可以使用 S4 [=24] =]是的。主要问题是像

这样的表达式
server$foo$bar$baz 

会被翻译成一系列调用,例如

$($($(server,"foo"),"bar"),"baz")

但与普通函数嵌套不同的是,每个内部调用在进入下一层嵌套之前似乎都经过了全面评估。这真的不可能仅仅在第一个 $ 之后拆分所有内容,因为这不是它的解析方式。但是,您可以让 $ 函数 return 另一个对象并将所有值附加到该对象。这是示例 S4 class

setClass("Server", slots=list(el="character"))
setMethod("$", signature(x="Server"), 
   function(x,name) {
    xx <- append(slot(x,"el"),name)
    new("Server", el=xx)
   }
)

server <- new("Server")    
server$foo$bar$baz

# An object of class "Server"
# Slot "el":
# [1] "foo"   "bar" "baz"

唯一的问题是如果您想对这些参数执行任何操作,我无法知道您何时位于列表的末尾。