2011-02-10 6 views
13

Definire un oggetto della classe S3 "bar" e un metodo di stampa:Ottenere il nome dell'oggetto per S3 metodo di stampa in mancanza

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

Ora Stampa (foo) fa questo:

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

Grande, ma auto-stampa non riesce:

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

sto indovinando questo è qualcosa a che fare con il modo in cui la linea viene valutata come espressione di alto livello. Ho fatto una rapida ricerca su R-Devel senza successo. qualcuno sa come ripararlo?

Il motivo per cui voglio il nome è perché la cosa che sto definendo è una funzione, e voglio essere in grado di mettere 'try foo (2)' nel metodo di stampa (ottenendo 'foo' dal nome del oggetto). Sì, puoi eseguire la sottoclasse di funzioni in S3. Suppongo che ci possano essere altri pifani ..

risposta

8

questo è un caso un po 'particolare, in quanto R sostituisce foo dal suo valore prima di chiamare print quando si digita il nome sulla riga di comando. Ciò può essere illustrato da:

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, senza il nome come un attributo (come Aaron mostrato), non v'è alcun modo sulla terra si estrae il nome dell'oggetto da qualsiasi luogo. Semplicemente non è presente nel callstack.

+0

Sì, sembra che non si possa fare. Potrei dare un'occhiata alla fonte per vedere esattamente come accade. Grazie! – Spacedman

5

Se non si intende rinominare l'oggetto, è possibile includere il nome come attributo e stamparlo.

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

Poi fa quello che ci si aspetta:

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

A meno che non si utilizza un nome diverso per lo stesso oggetto:

> fooX <- foo 
> fooX 
print.bar says this was foo