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

发布于 2024-10-16 17:25:34 字数 583 浏览 5 评论 0原文

定义 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 中对函数进行子类化。我想可能还有其他的陷阱..

Define an object of S3 class "bar" and a print method:

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

Now print(foo) does this:

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

Great, but auto-printing fails:

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

I'm guessing this is something to do with the way the line is evaluated as a top-level expression. Had a quick search on R-devel to no avail. Anyone know how to fix it?

The reason I want the name is because the thing I am defining is a function, and I want to be able to put 'try foo(2)' in the print method (getting 'foo' from the name of the object). Yes, you can subclass functions in S3. I suppose there may be other pifalls..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

虫児飞 2024-10-23 17:25:34

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

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 所示),那么您根本无法从任何地方提取对象的名称。它根本不存在于调用堆栈中。

This is a rather special case, as R substitutes foo by its value before calling print when you type the name at the command line. This can be illustrated by :

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)

ergo, without the name as an attribute (like Aaron showed), there is no way on earth you'll extract the name of the object from anywhere. It's simply not there in the callstack.

用心笑 2024-10-23 17:25:34

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

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 

If you're not going to be renaming the object, you could include the name as an attribute and print that instead.

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

Then it does what you expect:

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

Unless you use a different name for the same object:

> fooX <- foo
> fooX
print.bar says this was foo 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文