そのため、説明属性を追加するために、また S3 ジェネリックを使用してすべてを処理するために、R で構築しているいくつかの関数のクラスを変更しています。基本的に、私は次のような構造を持っています
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()
て別の名前を付け、後で操作するというアイデアを試しました。ただし、これは機能しません。ここで何が起こっているかについての情報があれば幸いです。
> 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
このことから、何らかの理由で、 、op
、args
およびの 4 つの引数のうち少なくとも 2 つrho
が現在必要であると結論付けています。の署名から、渡される 4 つの引数は、呼び出し、約束、引数のリスト、そしておそらく環境であるとdo_function()
推測しています。do_function
(これらの引数を 2 つまで NULL に設定するなど)についてさまざまな組み合わせを試しましたが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"
CheckFormals()
このエラー メッセージは、私も調べたC 関数から返されます。
/* 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
でないのはなぜですか?R で同一と見なされるのに、function2
なぜ別の構文を使用して呼び出す必要があるのですか?function2
- 実際に関数を定義する
function2
ような適切な引数は何ですか?function2([arguments])