为R函数编写装饰器

为R函数编写装饰器,r,R,一位同事最近正在查看通话图,想看看什么叫什么。我们使用mvbutils中的foodweb对其进行了分类,但我想知道如何最好地在R中创建一个装饰器(用python语言) instrument=function(z){ force(z) n=deparse(substitute(z)) # get the name f=function(...){ cat("calling ", n,"\n") x=z(...) cat("done\n") return(x)

一位同事最近正在查看通话图,想看看什么叫什么。我们使用mvbutils中的foodweb对其进行了分类,但我想知道如何最好地在R中创建一个装饰器(用python语言)

instrument=function(z){
  force(z) 
  n=deparse(substitute(z)) # get the name
  f=function(...){
   cat("calling ", n,"\n")
   x=z(...)
   cat("done\n")
   return(x)
   }
  return(f)
}
这让我可以做到:

> foo=function(x,y){x+y}
> foo(1,2)
[1] 3
现在,我可以通过包装函数来创建函数日志:

> foo=instrument(foo)
> foo(1,2)
calling  foo
done
[1] 3

比如说,在一个软件包中,以前是否做过这样的事情,我是否错过了任何会破坏我做这件事的方法的问题?

R中的
trace
函数就是这样做的。请参阅
?trace

我的github包标签试图解决此问题

您的示例可以按如下方式解决:

#遥控器::安装_github(“moodymudskipper/tag”)
图书馆(标签)
德科[1]3
foo2呼叫foo
#>完成
#> [1] 3
deco2呼叫foo
#>完成
#> [1] 3
由(v0.3.0)于2020年1月30日创建

标记是函数操作符工厂(或副词工厂),这里
deco
是标记,
deco(quote(message(“calling foo”))、quote(message(“done”))
是副词,方法是
$
。这意味着您可以运行
deco(quote(message(“calling foo”))、quote(message(“done”)))(foo)(1,2)
,但美元符号使其更加友好

标记定义具有默认参数(默认值是必需的,不支持点)和有点像新主体的
模式,使用特殊函数
t_ARGS()
F_ARGS()
F_ARGS()
F_FORMALS()
CALL()
访问标记或函数的参数或形式以及调用本身(请参见
?标记::调用

实现了一些更神奇的功能,因此可以将标记的参数赋予标记函数本身,因此也可以执行以下操作:

deco$foo(1, 2, quote(message("calling foo")), quote(message("done")))
#> calling foo
#> done
#> [1] 3
foo2 <- deco$foo
foo2(1, 2, quote(message("calling foo")), quote(message("done")))
#> calling foo
#> done
#> [1] 3
deco$foo(1,2,引号(消息(“调用foo”)),引号(消息(“完成”))
#>打电话给福
#>完成
#> [1] 3
foo2呼叫foo
#>完成
#> [1] 3
在这些情况下,您可以在RStudio中享受自动完成功能:

更多信息:
该软件包包含了一系列这样的“装饰者”

公平的问题,错误的观众。显然,你需要在
r-devel
上问这个问题。只要Gabor在听众中,他就是正确的听众。问得好。虽然答案已被接受,但我希望看到一个更加规范/百科全书式的答案:)