I have encountered two instances where it seems that R treats obj and print(obj) differently. I would like to know more about the nature of this difference.
I can run
trace("print.default", where = print)
to trace the default print function.
And indeed, this seems to work as expected:
> print("Hello world!")
Tracing print.default("Hello world!") on entry
[1] "Hello world!"
However, this does not work if I rely on the auto-print behavior:
> "Hello world!"
[1] "Hello world!"
Why is the tracing code not run for auto-printed objects in R? How can I change that?
I can define a print method for NULL objects:
.S3method("print", "NULL", function(x, ...) cat("NULL object\n"))
Again, this works when calling print() explicitly:
> print(NULL)
NULL object
But not when relying on auto-printing:
> NULL
NULL
Why does R not dispatch to my custom print function? How can I make it work?
The instances 1 and 2 defy my expectations in a similar way, so I assume there may be a common cause. What is it?
As Nir Graham suggested in the answer on a similar question, R Internals is enlightening in this regard, in particular the section on autoprinting:
The actual autoprinting is done by
PrintValueEnvin fileprint.c. If the object to be printed has the S4 bit set and S4 methods dispatch is on,showis called to print the object. Otherwise, if the object bit is set (so the object has a"class"attribute),print.defaultis called.
In other words, as "Hello world!" and NULL have no class attribute set, print() is never called. Indeed, adding the class attribute resolves the situation for the first instance:
> structure("Hello world!", class = "any_class")
Tracing print.default(x) on entry
[1] "Hello world!"
attr(,"class")
[1] "any_class"
For the second instance, as NULL cannot have attributes, this can be demonstrated with numerics instead:
> .S3method("print", "numeric", function(x, ...) cat("numeric object\n"))
> print(3)
numeric object
> 3
[1] 3
> structure(3, class = "numeric")
numeric object
print.c puts it succinctly:
/*
* 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.
*/
Consequently, there should be no way to change the way objects without a class are auto-printed at the top-level.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With