2016-01-06 11 views
7

Quando si stampa qualcosa direttamente sulla console (digitare un nome variabile, ad esempio, anziché utilizzare la funzione di stampa print(x)), mi piacerebbe che fosse stampato in modo diverso dal modo in cui normalmente stampa. La mia idea è che la stampa sia fatta per una qualche funzione. Se è così, tutto ciò che devo fare è sostituire quella funzione con una funzione mia. Tuttavia, non riesco a capire quale sia la funzione interna che fa la stampa.Modifica del modo in cui l'output viene stampato sulla console

Ecco cosa ho provato finora.

.real_cat = cat 
cat = function(x) .real_cat("*** cat ***", x, "\n") 

cat(2345) 
2345 # no 

stampa per consolare non è fatto tramite cat. Che mi dici di print?

.real_print = print 
print = function(x) .real_cat("*** print ***", x, "\n") 
print(2345) 
2345 # no 
"hello" # no 
I(2345) # yes 

Alcune classi, come AsIs, vengono stampate a consolare via print, ma altri, come numeric o character non lo sono. :-(

c("print.numeric", "print.character", "print.AsIs", "print.default") %in% methods("print") 
# FALSE FALSE TRUE TRUE 

Risulta print non ha nemmeno un metodo separato per la stampa numeric o character. Le classi che hanno un metodo di print vengono stampati sulla console usando print. Ma le classi che non hanno un metodo print non sono. Forse sono stampati con il metodo default?

print.default = function(x) .real_cat("*** print.default ***", x, "\n") 
print.default(2345) 
2345 # no 
"hello" # no 

No.

Forse se definire un metodo per la numerica, quindi lo stamperà utilizzando tale metodo?

print.numeric = function(x) .real_cat("*** print.numeric ***", x, "\n") 
print.numeric(2345) 
2345 # no 

print.character = function(x) .real_cat("*** print.character ***", x, "\n") 
print.character("hello") 
"hello" # no 

Qui è dove rimango bloccato. Non riesco a capire in alcun modo di avere alcune classi di base come numeric o character stampare direttamente alla console utilizzando la mia funzione di stampa.

Se questo aiuta, ecco la ragione per cui voglio farlo. Sto scrivendo un pacchetto per valori abbastanza stampati (https://github.com/prettyprint/prettyprint). Troppe volte, l'output di un'analisi è troppo difficile da leggere e quindi capire. Sì, puoi renderlo carino usando format, signif e round, ed è praticamente ciò che il pacchetto già fa per te in background.

Mi piacerebbe rendere la stampa più semplice possibile per l'utente. A questo punto, devono chiamare la mia bella funzione di stampa (pp(x)). Mi piacerebbe giocare con dando all'utente la possibilità di avere il risultato bella stampa automaticamente. (Vorrei stampare sia la non bella e la versione piuttosto del valore, per assicurarsi che nulla si perde nella prettifying.)

+0

Una soluzione con classi implicite sarebbe di aggiungere un attributo class all'oggetto e utilizzare un metodo 'print'. Per esempio. 'print.numeric = function (x, ...) cat (" numerico: \ n ", unclass (x)," \ n "); xx = c (1, 2, 3); xx; attr (xx, "class") = "numerico"; xx'. O potresti definire la tua "classe" e il suo metodo 'print'. –

risposta

6

Vedi questo commento in the source:

* print.default() -> do_printdefault (with call tree below) 
* 
* auto-printing -> PrintValueEnv 
*      -> PrintValueRec 
*      -> call print() for objects 
* Note that auto-printing does not call print.default. 
* PrintValue, R_PV are similar to auto-printing. 
* 
* do_printdefault 
* -> PrintDefaults 
* -> CustomPrintValue 
*  -> PrintValueRec 
*   -> __ITSELF__ (recursion) 
*   -> PrintGenericVector -> PrintValueRec (recursion) 
*   -> printList   -> PrintValueRec (recursion) 
*   -> printAttributes  -> PrintValueRec (recursion) 
*   -> PrintExpression 
*   -> printVector  >>>>> ./printvector.c 
*   -> printNamedVector >>>>> ./printvector.c 
*   -> printMatrix  >>>>> ./printarray.c 
*   -> printArray  >>>>> ./printarray.c 

Di conseguenza, l'auto-stampa può solo coinvolgere il metodo di invio per classi esplicite (con un attributo di classe, ovvero oggetti). Presumo che un numeric sia gestito da printVector. Si prega di controllare da soli.

I aggiunge una classe AsIs (creando un oggetto) e quindi print.AsIs viene spedito:

class(I(3)) 
#[1] "AsIs" 
+0

Vedo qui https://github.com/wch/r-source/blob/trunk/src/main/printvector.c una funzione C chiamata 'printVector'. Come faccio a capire quale funzione R la chiama? – prettyprint

+0

Questo è tutto gestito a livello C. A meno che non si stia stampando un oggetto, la stampa automatica non coinvolge le funzioni R. – Roland

Problemi correlati