2016-01-06 16 views
7

Kiedy drukuję coś bezpośrednio na konsoli (wpisz nazwę zmiennej, na przykład x, zamiast używać funkcji drukowania print(x)), chciałbym, aby drukował inaczej niż sposób, w jaki zwykle drukuje. Mój pomysł polega na tym, że drukowanie odbywa się za pomocą jakiejś funkcji. Jeśli tak jest, wszystko, co muszę zrobić, to zastąpić tę funkcję funkcją własną. Nie mogę jednak określić, jaka jest wewnętrzna funkcja drukowania.Zmiana sposobu drukowania wydruku na konsolę

Oto, co próbowałem do tej pory.

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

cat(2345) 
2345 # no 

Drukowanie na konsolę nie odbywa się za pośrednictwem cat. A co z numerem print?

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

Niektóre klas, jak AsIs, drukowane są do konsoli poprzez print, ale inni, jak numeric lub character nie są. :-(

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

Okazuje się print nawet nie mają oddzielną metodę drukowania numeric lub character. Klasy, które mają metodę print są wypisywane na konsoli przy użyciu print. Ale klas, które nie mają metodę print nie są. Możliwe są drukowane przy użyciu metody default?

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

nr

Może jeśli określenie metody numeryczne, następnie będzie wydrukować go za pomocą tej metody?

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 

Oto, gdzie utknąłem. Nie mogę wymyślić, aby niektóre podstawowe klasy, takie jak numeric lub character, były drukowane bezpośrednio na konsoli przy użyciu mojej własnej funkcji drukowania.

Jeśli to pomaga, oto powód, dla którego chcę to zrobić. Piszę pakiet do wartości drukowanych (https://github.com/prettyprint/prettyprint). Zbyt wiele razy wynik analizy jest zbyt trudny do odczytania, a zatem zrozumieć. Tak, możesz sprawić, że będzie pięknie, używając format, signif i round, i to w zasadzie to, co pakiet robi dla ciebie w tle.

Chciałbym, aby drukowanie było jak najłatwiejsze dla użytkownika. W tym momencie muszą zadzwonić do mojej funkcji "pretty-print" (pp(x)). Chciałbym się pobawić, dając użytkownikowi opcję automatycznego drukowania wyniku. (Chciałbym drukować zarówno non-ładny i całkiem wersja wartości, aby upewnić się, że nic nie jest stracone w prettifying.)

+0

Obejście z klas ukrytych byłoby dodać atrybut class do obiektu i użyj metody 'print'. Na przykład. 'print.numeric = funkcja (x, ...) cat (" numeric: \ n ", unclass (x)," \ n "); xx = c (1, 2, 3); xx; attr (xx, "class") = "numeric"; xx'. Możesz też zdefiniować własną "klasę" i jej metodę "print". –

Odpowiedz

6

Zobacz ten komentarz w 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 

konsekwencji, automatyczne drukowanie może wiązać się tylko z wysyłką metod dla klas jawnych (z atrybutem klasy, czyli obiektami). Zakładam, że numeric jest obsługiwane przez printVector. Sprawdź to sam.

I dodaje klasę AsIs (tworzenie obiektu), a następnie print.AsIs jest wywoływane:

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

Widzę tutaj https://github.com/wch/r-source/blob/trunk/src/main/printvector.c funkcję C o nazwie 'printVector'. Jak mogę się dowiedzieć, która funkcja R nazywa to? – prettyprint

+0

To wszystko jest obsługiwane na poziomie C. Jeśli nie drukujesz obiektu, automatyczne drukowanie nie obejmuje funkcji R. – Roland

Powiązane problemy