【问题标题】:Creating dynamically methods in R6Class, magic of print(ls.str()) [duplicate]在 R6Class 中创建动态方法,print(ls.str()) 的魔力 [重复]
【发布时间】:2015-12-08 23:32:06
【问题描述】:

在 R 中,我想创建一个类(R6Class),在调用初始化时创建几个动态方法(方法的数量及其名称取决于初始化中的参数)。但是我遇到了环境的奇怪问题。

这是一个不工作的简化版代码。

library(R6)

ffactory <- function(i) {
  function() i
}

A <- R6Class(
  lock_objects=FALSE,
  public=list(
    initialize=function(args) {
      for (i in args) {
        self[[i]] <- ffactory(i)
      }
    }
  )
)

a <- A$new(c('a', 'b', 'c'))

现在:

> a$a()
[1] "c"
> a$b()
[1] "c"
> a$c()
[1] "c"

为了找出问题所在,我在 ffactory 函数中添加了一行打印环境的行。那是

ffactory <- function(i) {
  print(ls.str())
  function() i
}

现在它已经开始工作了!!!

> a$a()
[1] "a"
> a$b()
[1] "b"
> a$c()
[1] "c"

那为什么?应该有什么我不明白的。观察者效应还是什么? :)

print(ls.str()) 这行有什么魔力?实际上我不能从这条线上删除printstr。当然,有这样的台词是很愚蠢的。更不用说屏幕上的垃圾了。

【问题讨论】:

    标签: r r6


    【解决方案1】:

    您遇到过惰性求值 - R 在求值 i 之前会一直等待 - 在前一种情况下,i 在所有情况下都将以其最后一个值求值。 printls.str 的组合并没有什么特别之处;在您的方法调用(a$a()a$b() 等)之前强制评估 i 的任何东西都会做同样的事情。

    正式地说,这就是force 的用途:

    ffactory <- function(i) {
      force(i);
      function() i
    }
    
    R> a$a()
    #[1] "a"
    R> a$b()
    #[1] "b"
    R> a$c()
    #[1] "c"
    

    但是,这也恰好可以完成这项工作:

    ffactory <- function(i) {
      #force(i);
      .z <- capture.output(cat(i, "\n"))
      function() i
    }
    
    R> a$a()
    #[1] "a"
    R> a$b()
    #[1] "b"
    R> a$c()
    #[1] "c"
    

    大概有无数种强制评估的方法;不过,我认为使用force 可以使您的意图最清楚。

    直接引用帮助文件,

    force 强制对形式参数进行评估。这可能很有用 如果参数将被词法作用域捕获在闭包中 规则,稍后将通过显式分配或 循环或应用函数中的隐式赋值。

    随后,

    这是语义糖:只需评估符号即可 东西(见例子)。

    其实看看force是怎么定义的,

    R> force
    #function (x) 
    #  x
    #<bytecode: 0x3b7b528>
    #<environment: namespace:base>
    

    你甚至可以逃脱

    ffactory <- function(i) {
      i; function() i
    }
    

    但如前所述,我认为显式调用 force 将使您的代码更具可读性。

    【讨论】:

    • 呵呵呵呵。非常感谢!在惰性求值函数 function() i 中包含惰性参数 i 有点有趣,该函数在非惰性求值函数中。
    • 当然,如果它解决了您的问题,请随时接受我的回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-27
    • 2017-08-06
    • 1970-01-01
    • 2020-07-17
    • 1970-01-01
    相关资源
    最近更新 更多