13

定义一个 S3 类“bar”的对象和一个打印方法:

foo=list(1)
class(foo) <- c("bar")
print.bar <- function(x,...){
  cat("print.bar says this was ",deparse(substitute(x)),"\n")
}

现在 print(foo) 这样做:

> print(foo)
print.bar says this was  foo 

很好,但自动打印失败:

> foo
print.bar says this was  structure(list(1), class = "bar")

我猜这与将行评估为顶级表达式的方式有关。快速搜索 R-devel 无济于事。谁知道怎么修它?

我想要这个名字的原因是因为我定义的是一个函数,并且我希望能够将“try foo(2)”放在 print 方法中(从对象的名称中获取“foo”)。是的,您可以在 S3 中对函数进行子类化。我想可能还有其他陷阱..

4

2 回答 2

8

这是一个相当特殊的情况,因为当您在命令行键入名称时,Rfoo在调用之前会用它的值替换。print这可以通过以下方式说明:

foo=list(1)
class(foo) <- c("bar")
print.bar <- function(x,...){
  print(sys.calls())
}

> foo
[[1]]
print(list(1))

[[2]]
print.bar(list(1))

> print(foo)
[[1]]
print(foo)

[[2]]
print.bar(foo)

因此,如果没有名称作为属性(如 Aaron 所示),您将无法从任何地方提取对象的名称。它根本不在调用堆栈中。

于 2011-02-10T21:39:20.493 回答
5

如果您不打算重命名对象,则可以将名称作为属性包含并打印出来。

foo <- structure(list(1), class="bar", name="foo")
print.bar <- function(x,...){
  cat("print.bar says this was",attr(x, "name"),"\n")
}

然后它会做你所期望的:

> print(foo)
print.bar says this was foo 
> foo
print.bar says this was foo 

除非您对同一对象使用不同的名称:

> fooX <- foo
> fooX
print.bar says this was foo 
于 2011-02-10T19:06:19.957 回答