【问题标题】:Dynamically Generate Reference Classes动态生成引用类
【发布时间】:2013-04-23 15:43:12
【问题描述】:

我正在尝试在 R 包中动态生成引用类,但事实证明这相当困难。以下是我采用的方法和遇到的问题:

我正在创建一个包,我希望能够在其中动态读取模式并自动生成关联的引用类(想想 SOAP)。当然,这意味着我无法在包源中预先定义我的引用类。

我最初尝试使用简单的方法创建一个新类:

myClass <- setRefClass("NewClassName", fields=list(fieldA="character"))

当然,在交互执行时可以正常工作,但是当包含在包源中时,我收到 locked binding 错误。从我的阅读来看,发生这种情况是因为在交互运行时,类信息存储在未锁定的全局环境中,而我的包的基本环境被锁定。

然后我发现了一个帖子,建议使用以下内容:

myClass <- setRefClass("NewClassName", fields=list(fieldA="character"), where=globalenv())

当我尝试构建包时,这实际上使 R/Studio 崩溃了,所以很遗憾,我没有它产生的错误的日志,但它肯定没有工作。

接下来我尝试在我的包中创建一个新环境,我可以使用它来存储这些引用类。所以我在我的包源中添加了一个.classEnv &lt;- new.env() 行(不在任何函数内部),然后在创建新的引用类时尝试使用这个类:

myClass <- setRefClass("NewClassName", fields=list(fieldA="character"), where=.classEnv) 

这实际上似乎工作正常,但会产生以下警告:

> myClass <- setRefClass("NewClassName", where=.classEnv)
Warning message:
In getPackageName(where) :
  Created a package name, ‘2013-04-23 10:19:14’, when none found

那么,出于某种原因,methods::getPackageName() 无法获取我的新环境所在的包?

有没有办法以不同的方式创建我的新环境,以便getPackageName() 可以正确识别包?我可以添加一些功能来帮助getPackageName() 检测包裹吗?如果我可以处理警告,这是否可行,或者我是否通过尝试动态创建引用类来滥用它们?

【问题讨论】:

  • ?setRefClass 表示参数... 被传递给?setClass,这有参数package;你想采取你的第三种方法,有论点package='YourPackage' 什么的?
  • 谢谢你的小费,马丁。不幸的是,这无法消除错误。看起来包名称并没有一直延伸到 getPackageName,如果尚未指定 .packageName 变量,则警告来自这里。

标签: r reference-class


【解决方案1】:

为了进行对话,我发现getpackageName 将包名存储在指定环境中的隐藏.packageName 变量中。

所以你实际上可以绕过警告

assign(".packageName", "MyPkg", envir=.classEnv)    
myClass <- setRefClass("NewClassName", fields=classFields, where=.classEnv)

这解决了警告,但文档说不要无限期地信任 .packageName 变量,我仍然觉得我在破解这个问题,并且可能误解了一些关于引用类及其与环境的关系的重要内容。

来自文档的完整详细信息:

包名通常在加载包的过程中通过安装脚本或库函数安装。 (目前,名称存储为对象 .packageName 但以后不要相信它。)


编辑

进一步阅读后,setPackageName 方法可能是为环境设置包名的更可靠方法。根据文档:

setPackageName 可用于在没有包名的环境中建立包名。这允许您在任意环境中创建类和/或方法,但通常最好通过标准 R 编程工具(package.skeleton 等)创建包。

所以看起来一个有效的解决方案如下:

setPackageName("MyPkg", .classEnv)
myClass <- setRefClass("NewClassName", fields=classFields, where=.classEnv)

这消除了警告消息,并且不依赖于任何记录为不稳定的内容。我仍然不清楚为什么它是必要的,但是......

【讨论】:

    猜你喜欢
    • 2012-02-07
    • 1970-01-01
    • 2013-09-18
    • 2013-03-08
    • 1970-01-01
    • 1970-01-01
    • 2018-09-24
    • 1970-01-01
    • 2018-11-30
    相关资源
    最近更新 更多