r - 如何将 S3 方法声明为默认加载环境?

标签 r namespaces r-s3

在一个包中,我想为对象 foobar 调用一个 S3 方法“紧凑” .

因此会有一个 compact.foobar函数在我的包中,以及 compact函数本身:

compact = function(x, ...){
    UseMethod("compact", x)
}

但是,后者会与 purrr::compact 相冲突。 .

我可以默认使用 purrr 的方法( compact.default = purrr::compact ,或者也许compact.list = purrr::compact ),但如果用户没有 purrr,这将毫无意义。加载。

如何将我的方法默认为 compact 的加载版本,在用户环境中? (以便它使用 purrr::compact ,任何其他声明的 compact 函数,或缺少函数失败)

最佳答案

不幸的是,S3 不能很好地处理这种情况。您必须手动搜索合适的功能。以下工作,或多或少:

get_defined_function = function (name) {
    matches = getAnywhere(name)
    # Filter out invisible objects and duplicates
    objs = matches$objs[matches$visible & ! matches$dups]
    # Filter out non-function objects
    funs = objs[vapply(objs, is.function, logical(1L))]
    # Filter out function defined in own package.
    envs = lapply(funs, environment)
    funs = funs[! vapply(envs, identical, logical(1L), topenv())]
    funs[1L][[1L]] # Return `NULL` if no function exists.
}
compact.default = function (...) {
    # Maybe add error handling for functions not found.
    get_defined_function('compact')(...)
}

这使用 getAnywhere查找所有名为 compact 的对象R 知道的。然后过滤掉那些不可见的,因为它们不在附加的包内,以及那些重复的(这可能是多余的,但我们还是这样做了)。

接下来,它过滤掉任何不是函数的东西。最后它过滤掉了 compact我们自己的包定义的 S3 泛型。为此,它将每个函数的环境与包环境(由 topenv() 给出)进行比较。

这应该可以工作,但是如果在不同位置定义了多个具有相同名称的函数(它只是首先选择一个任意一个),它没有关于首选哪个函数的规则,并且它也不检查函数签名是否匹配(在 R 中很难做到这一点,因为函数调用和参数匹配非常灵活)。

关于r - 如何将 S3 方法声明为默认加载环境?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60979867/

相关文章:

R 没有连接到 HDFS

PHP 命名空间和全局自动加载单个文件

r - 在R中安全创建S3泛型

r - rep 真的是泛型吗?

R数据表根据条件分组并根据条件获取计数

r - 是否可以通过扫描从控制台读取而不回显字符?

c++ - RcppArmadillo faSTLm 结果与 R 的 lm 不同,我做错了什么?

c++ - 没有命名空间标准的 friend 重载运算符

c# - 命名空间 'Device' 中不存在类型或命名空间名称 'System'

r - 如何在 R 中为自定义 S3 类编写 c() 函数