当我为类生成器提供不同的名称时(这有合理的理由),我开始遇到问题:
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
,则不会出现上述错误。
如果这种行为是设计的,为什么?如果这是一个错误,那么我该如何解决这个问题呢?生成器和类具有不同名称会导致另一个隐藏的问题吗?
答案 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
。