获取S3打印方法的对象名称失败

Spa*_*man 13 r r-s3

定义S3类"bar"的对象和打印方法:

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

现在print(foo)执行此操作:

> print(foo)
print.bar says this was  foo 
Run Code Online (Sandbox Code Playgroud)

很好,但自动打印失败:

> foo
print.bar says this was  structure(list(1), class = "bar")
Run Code Online (Sandbox Code Playgroud)

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

我想要这个名字的原因是因为我定义的东西是一个函数,我希望能够在print方法中放入'try foo(2)'(从对象名称中获取'foo').是的,您可以在S3中子类化函数.我想可能还有其他的pifalls ..

Jor*_*eys 8

这是一个相当特殊的情况,因为当您在命令行键入名称时,R foo在调用之前将其替换为其值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)
Run Code Online (Sandbox Code Playgroud)

ergo,没有作为属性的名称(如Aaron所示),地球上没有办法从任何地方提取对象的名称.它只是在callstack中没有.


Aar*_*ica 5

如果您不打算重命名该对象,则可以将该名称作为属性包含在内,然后将其打印出来.

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

然后它做你期望的:

> print(foo)
print.bar says this was foo 
> foo
print.bar says this was foo 
Run Code Online (Sandbox Code Playgroud)

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

> fooX <- foo
> fooX
print.bar says this was foo 
Run Code Online (Sandbox Code Playgroud)