因此,我正在更改我在 R 中构建的一些函数的类,以便添加描述属性,并且因为我想使用 S3 泛型来为我处理所有事情。基本上,我有一个类似的结构
foo <- function(x) x + 1
addFunction <- function(f, description) {
class(f) <- c("addFunction", "function")
attr(f, "description") <- description
f
}
foo <- addFunction(foo, "Add one")
然后我做类似的事情
description <- function(x) UseMethod("description")
description.default <- function(x) deparse(substitute(x))
description.addFunction <- function(x) attr(x, "description")
这工作正常,但它不是那么优雅。我想知道是否可以定义一个新的函数类,以便可以用类似于语法的语法来定义此类的实例function
。换句话说,是否可以定义addFunction
以foo
下列方式生成的:
foo <- addFunction(description = "Add one", x) {
x + 1
}
(或类似的东西,我对应该将属性添加到函数的哪个位置没有强烈的感觉)?
谢谢阅读!
更新:我对这个想法做了更多的试验,但还没有真正达到任何具体的结果——所以这只是我当前(更新)对该主题的想法的概述:
我尝试了只复制function()
-function 的想法,给它一个不同的名称,然后再对其进行操作。但是,这不起作用,我很想对这里发生的事情进行任何输入:
> function2 <- `function`
> identical(`function`, function2)
[1] TRUE
> function(x) x
function(x) x
> function2(x) x
Error: unexpected symbol in "function2(x) x"
> function2(x)
Error: incorrect number of arguments to "function"
作为function()
一个原始函数,我尝试查看定义它的 C 代码以获取更多线索。我对电话中的错误信息特别感兴趣function2(x)
。底层的 C 代码function()
是
/* Declared with a variable number of args in names.c */
SEXP attribute_hidden do_function(SEXP call, SEXP op, SEXP args, SEXP rho)
{
SEXP rval, srcref;
if (TYPEOF(op) == PROMSXP) {
op = forcePromise(op);
SET_NAMED(op, 2);
}
if (length(args) < 2) WrongArgCount("function");
CheckFormals(CAR(args));
rval = mkCLOSXP(CAR(args), CADR(args), rho);
srcref = CADDR(args);
if (!isNull(srcref)) setAttrib(rval, R_SrcrefSymbol, srcref);
return rval;
}
由此,我得出结论,出于某种原因,现在需要四个参数、和 中call
的至少两个。根据我的签名,我猜测传递给的四个参数应该是一个调用、一个承诺、一个参数列表,然后可能是一个环境。我尝试了很多不同的组合(包括将这些参数中的两个设置为 NULL),但我不断收到相同的(新)错误消息:op
args
rho
do_function()
do_function
function2
> function2(call("sum", 2, 1), NULL, list(x=NULL), baseenv())
Error: invalid formal argument list for "function"
> function2(call("sum", 2, 1), NULL, list(x=NULL), NULL)
Error: invalid formal argument list for "function"
这个错误信息是从 C-function 返回的CheckFormals()
,我也查了:
/* used in coerce.c */
void attribute_hidden CheckFormals(SEXP ls)
{
if (isList(ls)) {
for (; ls != R_NilValue; ls = CDR(ls))
if (TYPEOF(TAG(ls)) != SYMSXP)
goto err;
return;
}
err:
error(_("invalid formal argument list for \"function\""));
}
我一点 C 语言都不流利,所以从这里开始我不太确定下一步该做什么。
所以这些是我更新的问题:
- 为什么不以同样
function
的function2
方式行事?function2
当它们在 R 中被视为相同时,为什么我需要使用不同的语法进行调用? - 真正定义函数的正确参数是
function2
什么?function2([arguments])