Reputation: 1610
Because it is on the list of Internal Generic Functions, I know that $
is an internal generic function. To my knowledge, this means that it cannot be extended using S3. Despite this, it is well-known that $
behaves differently for tibbles as it does data frames, implying that the developer of the tibble package have done what I believed to be impossible. How was this achieved? I tried to get the code for $.tibble
up in my IDE, but tibble::"$".tibble
returned nothing.
Upvotes: 1
Views: 90
Reputation: 206596
You can change behavior for internal generics if the first parameter is an object (is.object(x)==TRUE
). A tibble is an object. Most user created S3 classes are. Your problem before was you were trying to change the behavior for a matrix and a matrix is not an "object" so you cannot change the dispatch for internal generics for such objects.
Upvotes: 1
Reputation: 270348
Use the following to find examples in the base of R and in any loaded packages. (If the tibble package were loaded it would also list any $ methods in it although be aware that the class name of a tibble is not tibble .)
methods("$")
## [1] $,envRefClass-method $,refObjectGenerator-method
## [3] $.bibentry* $.DLLInfo
## [5] $.package_version $.person*
getAnywhere("$.bibentry")
## ...snip...
library(tibble)
tib <- tibble()
class(tib)
## [1] "tbl_df" "tbl" "data.frame"
getAnywhere("$.tbl_df")
## ..snip...
Here are some more examples assuming you have installed the relevant packages:
zoo:::"$.zoo"
proto:::"$.proto"
gsubfn:::"$.fn"
dyn:::"$.dyn"
or:
A key consideration is that the part after the $ is not evaluated even if you extend it.
Upvotes: 1