引用类生成器必须与类本身具有相同的名称吗?

时间:2014-01-17 07:05:33

标签: r oop reference-class

当我为类生成器提供不同的名称时(这有合理的理由),我开始遇到问题:

myClassGen <- setRefClass("myClass",
    methods = list(foo = function() baz())
)
myClassGen$methods(baz = function() "baz")

myObj <- myClassGen()
myObj$foo()

导致:

Error in myObj$foo() : could not find function "baz"

然而方法baz显然存在,因为我可以这样做:

> myObj$baz
Class method definition for method baz()
function () 
"baz"
<environment: 0x000000002c60f0b8>

如果生成器名称更改为myClass,则不会出现上述错误。

如果这种行为是设计的,为什么?如果这是一个错误,那么我该如何解决这个问题呢?生成器和类具有不同名称会导致另一个隐藏的问题吗?

1 个答案:

答案 0 :(得分:3)

您需要指定必须在类实例上调用baz(),因此.self

myClassGen <- setRefClass("myClass",methods = list(foo = function() .self$baz()))
myClassGen$methods(baz = function() "baz")

myObj <- myClassGen()
myObj$foo()
# [1] "baz"

因此,问题与类生成器的名称与类名不同有关,因为以下代码不起作用(请注意缺少.self):

myClass <- setRefClass("myClass", methods = list(foo = function() baz()))
myClass$methods(baz = function() "baz")

myObj <- myClass()
myObj$foo()
# Error in myObj$foo() : could not find function "baz"

参考类的官方文档为here


编辑(根据评论):

有关$methods(...)功能状态的部分中的文档:

  

新方法可以通过名称引用任何当前定义的方法   (包括此次调用$ methods()中提供的其他方法。注意   虽然之前定义的方法没有重新分析意义   他们不会调用新方法(除非它重新定义了一个   现有的同名方法)。

如果我理解正确,这意味着先前定义的方法baz无法调用新添加的方法foo。如果是这样,为什么.self$foo()工作正常? 我不确定,但我想这与上面文中提到的方法的分析有关。
可能会解析通过setRefClass定义的方法,并且如果找到对另一个类方法的调用,则调用以某种方式显式链接到该类方法,以避免与可能存在的具有相同名称的函数混淆(作为过度简化我想这些调用的前缀是.self$) 相反,对.self$something()的方法调用不会被修改,因为它们已经是显式的。

这似乎得到以下测试的合理支持。例如,如果我们运行此代码:

myClassGen <- setRefClass("myClass", methods = list(foo = function() baz(), 
                                                    baz = function() "baz"))
myObj <- myClassGen()
myObj$foo

我们得到:

Class method definition for method foo()
function () 
baz()
<environment: 0x000000000e490938>

 Methods used:  
    "baz"

您可以注意到最后一行说明baz方法使用了类方法foo

如果我们改为运行:

myClassGen <- setRefClass("myClass",methods = list(foo = function() .self$baz(), 
                                                   baz = function() "baz"))
myObj <- myClassGen()
myObj$foo

我们得到:

Class method definition for method foo()
function () 
.self$baz()
<environment: 0x00000000107ab5c8>

其中没有提及类方法baz