我的 Github 包中的标签尝试解决这个问题。
你的例子可以如下解决:
library(tag)
deco <- tag(args = list(.first = NULL, .last = NULL), pattern = {
t_args <- T_ARGS()
eval.parent(t_args[[".first"]])
on.exit(eval.parent(t_args[[".last"]]))
CALL()
})
foo <- function(x, y) {Sys.sleep(1); x + y}
deco(quote(message("calling foo")), quote(message("done")))$foo(1, 2)
foo2 <- deco(quote(message("calling foo")), quote(message("done")))$foo
foo2(1, 2)
deco2 <- deco(quote(message("calling foo")), quote(message("done")))
deco2$foo(1, 2)
创建于2020年1月30日,使用reprex package (v0.3.0)
标签是函数操作器工厂(或副词工厂),这里的deco
是一个标签,deco(quote(message("calling foo")), quote(message("done")))
是一个副词,具有$
方法。这意味着您可以运行deco(quote(message("calling foo")), quote(message("done")))(foo)(1,2)
,但美元符号表示法使其更加友好。
标签定义包括默认参数(默认值是强制性的,不支持省略号)和一个pattern
,它有点像您的新主体,使用特殊函数T_ARGS()
、F_ARGS()
、F_ARGS()
、F_FORMALS()
和CALL()
来访问标签或函数的参数或形式以及调用本身(请参见?tag::CALL
)。
实现了一些更多的魔法,使得标记的参数可以传递给带有标记的函数本身,因此也可以执行以下操作:
deco$foo(1, 2, quote(message("calling foo")), quote(message("done")))
foo2 <- deco$foo
foo2(1, 2, quote(message("calling foo")), quote(message("done")))
在这些情况下,您可以在RStudio中享受自动完成功能:
![enter image description here](https://istack.dev59.com/VrhXA.webp)
更多信息:https://github.com/moodymudskipper/tag
标签包含一系列这样的“装饰器”。
r-devel
上提出这个问题。 - Dirk Eddelbuettel