提问者:小点点

如何为未计算的赋值表达式定义S3方法?


tl; dr:R CMD check在我为S3类实现泛型时抱怨

我需要定义一组S3泛型来遍历AST未计算的R表达式。

出于演示目的,请考虑以下S3泛型及其方法:

walk = function (x) UseMethod('walk')

walk.default = function (x) message('default')

walk.name = function (x) message('name')

walk.call = function (x) message('call')

这工作得很好:

tests = alist('2', c, f(1))

invisible(lapply(tests, walk))
default
name
call

但是,有相当多的调用表达式的S3类不是call;例如:

tests2 = alist(for (x in y) ., if (.) ., x <- .)
invisible(lapply(tests2, walk))
default
default
default

…哎呀。我希望这些表达式被视为调用。我可以通过添加更多方法来做到这一点:

walk.for = function (x) message('for')

walk.if = function (x) message('if')

`walk.<-` = function (x) message('<-')

# … and so on for other syntax constructs.

现在我在调用walk时得到了预期的结果:

for
if
<-

但是,这段代码是包的一部分,R CMD check抱怨walk的定义。

W  checking replacement functions ...
    ‘walk.<-’
  The argument of a replacement function which corresponds to the right
  hand side must be named ‘value’.

我明白为什么我会收到警告(事实上,这看起来像是为walk.定义替换函数的拙劣尝试)。但当然这不是替换函数,所以警告是误报。那么我应该如何为类实现S3泛型


共1个答案

匿名用户

编写R扩展,第1.5.2节注册S3方法提供了一种解决方法:

可以为S3method指定第三个参数,例如用作方法的函数

S3method(print, check_so_symbols, .print.via.format)

打印时。check_so_symbols是不需要的。

这意味着,而不是定义'走。

walk_assign = function (x) message('<-')

(与其他S3方法不同,函数名不重要。)

S3method(walk, '<-', walk_assign)

这实际上与调用相同。S3method('walk','

当然,正如Allan Cameron所评论的那样,一个可以说是更简单的解决方案是融合

walk.default = function (x) {
    if (inherits(x, '<-')) {
        message('<-')
    } else {
        message('default')
    }

}

但是,就我个人而言,我不喜欢将S3调度与if混合使用。