2011-02-10 4 views
13

Определить объект S3 класса «бар» и способ печати:Получение имени объекта для S3 метода печати неисправного

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

Теперь печать (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. Я полагаю, что могут быть и другие pifalls.

ответ

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) 

эргометра, без имени в качестве атрибута (как Аарон показал), нет никакого способа на земле, вы будете извлечь имя объекта из любой точки мира. Его просто нет в стоп-лотке.

+0

Да, похоже, это невозможно. Я мог бы взглянуть на источник, чтобы узнать, как это происходит. Спасибо! – Spacedman

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