r - 在 R6Class 中创建动态方法,print(ls.str()) 的魔力

标签 r r6

在 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()) ?实际上我无法删除 print也不str从这条线。当然,有这样的台词是很愚蠢的。更不用说屏幕上的垃圾了。

最佳答案

您遇到过延迟求值的情况 - R 在求值 i 之前会等待尽可能长的时间 - 在前一种情况下,i 将以其最后一个值求值在所有情况下。 printls.str 的组合并没有什么特别之处;任何强制在方法调用之前评估 i 的内容(a$a()a$b() 等... )也会做同样的事情。

正式来说,这就是 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 forces the evaluation of a formal argument. This can be useful if the argument will be captured in a closure by the lexical scoping rules and will later be altered by an explicit assignment or an implicit assignment in a loop or an apply function.

随后,

This is semantic sugar: just evaluating the symbol will do the same thing (see the examples).

事实上,看看force是如何定义的,

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

你甚至可以逃脱

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

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

关于r - 在 R6Class 中创建动态方法,print(ls.str()) 的魔力,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34168116/

相关文章:

R Shiny 应用程序: renderUI does not work with nested modules R6 classes

作为 R6 类成员函数的替换函数

r - 更新 R6 对象实例中的方法定义

r - R : remove specific pattern in multiple places without removing text in between instances of the pattern 中的字符串操作

r - 如何在 R 的 igraph 中排列网络?

r - htmlwidgets 的 Shiny 加载栏

r - 如何将 R6 类导入到包中?

r - 在 R 中如何对 R6 对象数组进行排序

r - 如何将 R 中的字符串中的连续整数组合在一起?

R:未构建包小插图