$ 是一个内部通用函数,那么 tibble 包是如何扩展它的呢?

$ is an internal generic function, so how did the tibble package extend it?

因为它在the list of Internal Generic Functions, I know that $ is an internal generic function. 上,这意味着它不能使用S3扩展。尽管如此,众所周知 $ 对于 tibbles 的行为与它对数据帧的行为不同,这意味着 tibble 包的开发人员已经完成了我认为不可能的事情。这是如何实现的?我试图在我的 IDE 中获取 $.tibble 的代码,但 tibble::"$".tibble 什么也没返回。

使用以下内容在 R 的基础和任何加载的包中查找示例。 (如果加载了 tibble 包,它还会列出其中的所有 $ 方法,但请注意,tibble 的 class 名称不是 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...

假设您已经安装了相关软件包,这里还有一些示例:

zoo:::"$.zoo"
proto:::"$.proto"
gsubfn:::"$.fn"
dyn:::"$.dyn"

或:

一个关键的考虑因素是 $ 之后的部分即使您扩展它也不会被评估。

如果第一个参数是对象 (is.object(x)==TRUE),您可以更改内部泛型的行为。 tibble 是一个对象。大多数用户创建的 S3 类 都是。您之前的问题是您试图更改矩阵的行为,而矩阵不是“对象”,因此您无法更改此类对象的内部泛型的调度。