当前位置 : 主页 > 网络推广 > seo >

检索从其关联对象定义S4引用类的实际源表达式

来源:互联网 收集:自由互联 发布时间:2021-06-16
简而言之(实际问题) 如何从getClass(“MyClass”)或getRefClass(“MyClass”)返回的对象中访问定义S4引用类(参见?setRefClass)的实际源代码/表达式(因此在获取后,不是通过调查实际的源文件)? 我
简而言之(实际问题)

如何从getClass(“MyClass”)或getRefClass(“MyClass”)返回的对象中访问定义S4引用类(参见?setRefClass)的实际源代码/表达式(因此在获取后,不是通过调查实际的源文件)?

我做过的功课

由于一切都是R中的对象,我可以检索源代码/表达式

1)通过简单地调查相应的对象来定期执行功能:

foo <- function(x) print(x)

> foo
function(x) print(x)

2)通过selectMethod获取特定方法的方法对象的形式方法:

setGeneric(name="myMethod", signature=c("x"),
    def=function(x) standardGeneric("myMethod")       
)
setMethod(
    f="myMethod", 
    signature=signature(x="numeric"), 
    definition=function(x) print(x)
)
def <- selectMethod(f="myMethod", signature=c(x="numeric"))

# Get actual source code/expression
> attributes(def)$srcref
function(x) print(x)

但S4参考类似乎有所不同:

setRefClass(Class="MyClass", fields=list(x.1="character"))

def <- getRefClass("MyClass")

# Inspect object >> no expression
> def
Generator object for class "MyClass":

Class fields:

Name:        x.1
Class: character

 Class Methods:  
    "callSuper", "copy", "export", "field", "getClass", "getRefClass", "import", 
"initFields", "show", "trace", "untrace"


 Reference Superclasses:  
    "envRefClass"

def.temp <- attributes(attributes(def)$.xData$def)

# Inspect attributes >> no expression
> attributes(def.temp)
$names
 [1] "fieldClasses"    "fieldPrototypes" "refMethods"      "refSuperClasses"
 [5] "slots"           "contains"        "virtual"         "prototype"      
 [9] "validity"        "access"          "className"       "package"        
[13] "subclasses"      "versionKey"      "sealed"          "class"          

# Alternatively:
> names(attributes(getClass("MyClass")))
 [1] "fieldClasses"    "fieldPrototypes" "refMethods"      "refSuperClasses"
 [5] "slots"           "contains"        "virtual"         "prototype"      
 [9] "validity"        "access"          "className"       "package"        
[13] "subclasses"      "versionKey"      "sealed"          "class"

我似乎无法找到存储精确定义类的实际源代码/表达式的属性.

只是为了确保:这个表达式是我想要访问的

setRefClass(Class="MyClass", fields=list(x.1="character"))

背景/动机

我使用S4参考类(?setRefClass)工作很多,因此像class inheritance这样的OOP方面在我的日常工作中发挥了重要作用.我还遵循“一个def def per file”范例以保持组织有序,因此各种类defs存储在单独的文件中,其中文件名对应于各个类的名称.

与生活中的一切一样,这种方法也有一些优点,但也有一些固有的缺点:

方面1

无论是短期还是长期,您最终都会得到一个继承结构,该结构与各个源文件的字母顺序不再匹配.因此,简单地一个接一个地获取一个文件将导致在某个特定点处出现错误,其中某些必需的超类尚未被采购.

dir.create("classes", showWarnings=FALSE)
write("setRefClass(Class=\"A\", contains=\"B\", fields=list(x.3=\"logical\"))", 
    file="classes/class_A.R")
write("setRefClass(Class=\"B\", contains=\"C\", fields=list(x.2=\"numeric\"))", 
    file="classes/class_B.R")
write("setRefClass(Class=\"C\", fields=list(x.1=\"character\"))", 
    file="classes/class_C.R")

class_A.R是文件夹类中的第一个文件,但是为了获取它,我们首先需要获取class_B.R(因为这个文件定义了B类),这反过来需要C类,因此需要class_C.R的先前源.

因此,正确的整理是:

c("class_C.R", "class_B.R", "class_A.R")

方面2

对于某些任务,您确实需要/需要“每个文件多个defs”范例:quick&在进行并行化时,将必要的对象/函数/类轻松分发到工作进程,在实际构建包时组织代码等.

path <- "classes/classes.R"
file.create(path)
write("setRefClass(Class=\"C\", fields=list(x.1=\"character\"))", 
    file=path, append=TRUE)
write("setRefClass(Class=\"B\", contains=\"C\", fields=list(x.2=\"numeric\"))", 
    file=path, append=TRUE)
write("setRefClass(Class=\"A\", contains=\"B\", fields=list(x.3=\"logical\"))", 
    file=path, append=TRUE)

广告方面1

我不喜欢保留某种手动整理参考来指定正确的采购订单的想法,因为我认为这是计算机可以轻松为我做的工作(找出正确的整理).你需要做的唯一事情是找出每个类的超类(它的依赖关系),然后检索正确的整理是一件小事.

编辑

如果有人感兴趣:我确实想出了一个有效的方法.如果您想查看一些代码,请给我留言.它基于解析(不评估)相应的类def源文件,以便研究列出超类的contains参数的值.然后对这些超类的源文件递归重复整个过程,直到最终得到正确的排序规则.这也不是那么费时.

这是大纲:

x <- list.files("classes", full.names=TRUE)    
code <- base::parse(file=x[1])

> code 
expression(setRefClass(Class="A", contains="B", fields=list(x.3="logical")))

superclasses <- eval(code[[1]][["contains"]])
> superclasses
[1] "B"

# Next: investigate source file for class 'B'

广告方面2

我也不喜欢手册和副本粘贴,所以我实现了一个例程,允许我合并存储在单个文件中或从相应对象中提取的源代码到单个“合并”文件(通过deparse(< source_code_expression>)并写入(…,append =真正)).对于类,正确的排序规则在这里也很重要,否则当您尝试获取合并文件时会再次出现错误.

对于这两个方面,能够选择如何获取类/函数/方法的实际源代码/表达式是很好的:

>或者根据调查存储在各自的代码
源文件(parse(file = *))
>或基于直接从中访问所需信息
各自的对象.

第二个选项是上述实际问题的链接.

命令的“源”代码未存储,因此您不会通过检查对象来查看它.

通过在控制台输入并按[ENTER]来查看setRefClass的源代码.请注意,您所做的只是将参数传递给函数…未定义新表达式.所以,当你getRefClass时,你得到的是类知道自己的一切.

您可以通过创建parseRefClassArgs函数来重建它,该函数可以重建setRefClass的参数.

网友评论