Получение имени объекта для метода печати S3

Определите объект класса "класс" класса S3 и метод печати:

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)" (получив "foo" от имени объекта). Да, вы можете подклассифицировать функции в S3. Я полагаю, что могут быть другие пифаллы.

Ответы

Ответ 1

Это довольно частный случай, поскольку 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)

ergo, без имени в качестве атрибута (как показал Аарон), на земле нет способа извлечь имя объекта из любого места. Это просто не существует в callstack.

Ответ 2

Если вы не собираетесь переименовывать объект, вы можете включить это имя в качестве атрибута и напечатать его.

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