【问题标题】:Using "[[ ]]" notation for reference class methods对引用类方法使用“[[ ]]”表示法
【发布时间】:2011-04-30 11:05:27
【问题描述】:

在试验 R 中的新引用类时,我注意到如果对方法使用“[[ ]]”表示法(X[[“doSomething”]] 而不是 X$doSomething)会出现一些奇怪的行为。这种表示法适用于字段,但我最初认为它不适用于方法,直到我发现如果执行“class(X$doSomething)”,然后可以使用“[[ ]]”。下面的简单示例说明了这一点。

setRefClass("Number", 
  fields = list(
    value = "numeric"
  ),
  methods = list(
    addOne = function() {
      value <<- value + 1
    }
  )
)

X <- new("Number", value = 1)

X[['value']]         # 1

X[["addOne"]]()      # Error: attempt to apply non-function
class(X[["addOne"]]) # NULL

class(X$addOne)      # "refMethodDef"

# Now the following works!
X[["addOne"]]()      # sets X$value = 2
class(X[["addOne"]]) # "refMethodDef"

我遇到这种情况的原因是因为我想将我的对象组合在一个列表中并创建一个“applyMethod”函数,该函数将指定的方法应用于其中的每个对象。因此,我需要将方法指定为字符串。有谁知道我该如何实现这一目标?

【问题讨论】:

  • 引用类应该被实例化为.A = setRefClass(&lt;...&gt;); .A$new()[[ 是用于会员访问吗?来自?ReferenceClasses 的API 是$。不妨在线条内着色。

标签: r reference-class


【解决方案1】:

这是一堂课

.A <-
    setRefClass("A",
                fields=list(x="numeric"),
                methods=list(foo=function() x))

如果我有一个实例 a 并想使用 '$' 构造对 'foo' 方法的调用,我可以

eval(substitute(a$FUN(), list(FUN="foo")))

所以我将创建一个 Alist 类,该类包含 A 类的元素列表(这可以通过编程方式强制执行),并且有一个将应用任意方法的 .delegate 方法到列表的所有元素。然后,我将添加一个委托 foo 的方法。

.delegate <- function(FUN, ...)
{
    lapply(elts, function(elt, ...) {
        eval(substitute(elt$FUN(...), list(FUN=FUN, ...)))
    })
}

.Alist <-
    setRefClass("Alist",
                fields=list(elts="list"),
                methods=list(
                  initialize = function(...) callSuper(elts=list(...)),
                  .delegate = .delegate,
                  foo=function() .delegate("foo")))

然后使用它

> aList <- .Alist$new(.A$new(x=1), .A$new(x=2))
> aList$foo()
[[1]]
[1] 1

[[2]]
[1] 2

【讨论】:

    【解决方案2】:

    基本上,R5 ref 类在必要时不会缓存该方法。这可能是一种延迟评估。

    当您通过$ 访问该方法时,就会发生缓存。 因此,AFAIK,无法通过 [[string]]

    访问该方法

    但您可以像这样使用 .dollarForEnvRefClass 找到解决方法:

    > X <- new("Number", value = 1)
    > ls(X@.xData)
    [1] "value" # no methods named "addOne" before caching
    > X[["addOne"]]
    NULL
    > methods:::.dollarForEnvRefClass(X, "addOne") # cache it
    Class method definition for method addOne()
    function () 
    {
        value <<- value + 1
    }
    <environment: 0x116a4aa00>
    > ls(X@.xData)
    [1] "addOne" "value"  # you can find it
    > X$value # value is 1
    [1] 1
    > X[["addOne"]]() # call the method
    > X$value  # the method works
    [1] 2
    

    如果您对更多细节感兴趣,请查看实现:
    http://svn.r-project.org/R/trunk/src/library/methods/R/refClass.R

    也许有更直接的方法。

    【讨论】:

    【解决方案3】:

    报告 r-devel 上的错误,以便 John Chambers 可以修复它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-18
      • 2013-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多