【问题标题】:Redundancy of Function Parse Trees in RR中函数解析树的冗余
【发布时间】:2013-06-11 21:02:52
【问题描述】:

在 R 中,我注意到 function 运算符的解析树似乎是多余的,因为它的第四个元素似乎总是由前三个元素组成。

例如,

> as.list(substitute(function(x = 1){x^2}))
[[1]]
`function`

[[2]]
[[2]]$x
[1] 1


[[3]]
{
    x^2
}

[[4]]
function(x = 1){x^2}

我注意到的一件事是第四个元素确实存储了输入函数的格式。

> as.list(substitute(function(x = 1){
+ x^2})[[4]]
function(x = 1){
x^2}

解析树中第四个元素的用途是什么?我唯一能看到它被使用的是如果你想逐字打印一个函数,你已经可以通过打印函数来做到这一点,例如

> f = function(x = 1){
+ x^2}
> f
function(x = 1){
x^2}

【问题讨论】:

  • 好问题;我在 R 语言定义中找不到任何东西,但我认为保留源引用正是为了能够保留(例如)cmets;如果我做s <- substitute(function(x=1){ ## a comment; x^2})(在分号处换行),那么str(s[[4]]) 表明它是一个srcref 对象。 srcref 类的方法看起来真的很神秘......(文档:stat.ethz.ch/R-manual/R-patched/library/base/html/srcfile.html
  • 另一个有趣的事情是在第四个元素上执行as.list,虽然我不知道结果列表代表什么。
  • @Ben 说得对。要确认第四个元素确实只是一个 srcref,请查看执行操作时会得到什么:options(keep.source=FALSE); as.list(substitute(function(x = 1){x^2}))。 (或者只检查第四个元素的类!)
  • @JonClaus:as.list(s[[4]]) 中描述了as.list(s[[4]]) 结果的含义:c(first_line, first_byte, last_line, last_byte, first_column, last_column, first_parsed, last_parsed) 指的是代表源代码的低级对象的索引。
  • @BenBolker:您不应该将您的 cmets 粘贴到答案面板中吗?

标签: r parse-tree


【解决方案1】:

显然这个组件是一个源码参考:它不容易定位在R language definition,但它的目的恰恰是为了保留原始源码的结构,尤其是cmets;例如

s <- substitute(function(x=1){ 
      ## a comment
       x^2})
str(s[[4]])
##  Class 'srcref'  atomic [1:8] 1 21 2 15 21 15 1 2
##   ..- attr(*, "srcfile")=Classes 'srcfilecopy', 'srcfile' <environment: 0x8a87634>

表明它是一个srcref 对象。神秘的数字 (1, 21, 2, 15, ...) 表示对代表源代码的较低级别对象的索引,如?srcfile 页面中所述(即c(first_line, first_byte, last_line, last_byte, first_column, last_column, first_parsed, last_parsed))。正如@SimonO101 指出的那样,有一个R Journal article by Duncan Murdoch 可能给出了最好的解释。

【讨论】:

    【解决方案2】:

    一些补充说明:

    1) 可以使用options(keep.source=FALSE) 禁用此功能(默认为TRUE):

    > as.list(substitute(function(x = 1){x^2}))
    [[1]]
    `function`
    
    [[2]]
    [[2]]$x
    [1] 1
    
    
    [[3]]
    {
        x^2
    }
    
    [[4]]
    NULL
    

    在这个list中,第一个元素是标识闭包对象的符号,第二个保存formals,第三个保存body。请注意,最后一个以“标准”方式打印。第四个元素将保存输入文本,如键入的那样。

    2) 如果你在控制台输入function(x = 1){x^2},R 会调用print.function,它接受useSource 参数。默认情况下这是TRUE,并导致 R 简单地重复存储在解析列表的第四个元素中的内容。将其设置为 FALSE 会强制 R 打印函数 body

    > options(keep.source=TRUE)
    > f <- function(x = 1){x^2}
    > f
    function(x = 1){x^2}
    > print.function(f)
    function(x = 1){x^2}
    > print.function(f, useSource=FALSE)
    function (x = 1) 
    {
        x^2
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-22
      • 2011-08-10
      • 2010-09-20
      • 1970-01-01
      • 1970-01-01
      • 2011-11-01
      相关资源
      最近更新 更多