Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
290 views
in Technique[技术] by (71.8m points)

r - Changing how output is printed to the console

When I print something directly to the console (type some variable name, such as x, rather than using the print function print(x)), I'd like it to print differently from the way that it normally prints. My idea is that the printing is done by some function. If that's the case, all I have to do is replace that function with a function of my own. However, I cannot figure out what the internal function that does the printing is.

Here is what I've tried so far.

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

cat(2345)
2345    # no

Printing to console is not done via cat. What about print?

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

Some classes, like AsIs, are printed to console via print, but others, like numeric or character are not. :-(

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

Turns out print doesn't even have a separate method for printing numeric or character. Classes that have a print method are printed to the console using print. But classes that do not have a print method are not. Maybe they are printed using the default method?

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

No.

Maybe if I define a method for numeric, then it will print it using that method?

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

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

Here is where I get stuck. I cannot figure out any way to have some basic classes like numeric or character print out directly to console using my own print function.

If this helps, here is the reason that I want to do this. I am writing a package to pretty-print values (https://github.com/prettyprint/prettyprint). Too many times, the output of an analysis is too hard to read, and therefore understand. Yes, you can make it pretty using format, signif, and round, and that's basically what the package already does for you in the background.

I would like to make pretty-printing as easy as possible for the user. At this point, they have to call my pretty-print function (pp(x)). I'd like to play around with giving the user the option to have the result pretty print automatically. (I would print both the non-pretty and the pretty version of the value, to make sure nothing is lost in the prettifying.)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

See this comment 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

Consequently, auto-printing can only involve method dispatch for explicit classes (with a class attribute, a.k.a. objects). I assume a numeric is handled by printVector. Please check this yourself.

I adds a class AsIs (creating an object) and then print.AsIs is dispatched:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...