【问题标题】:Internal S3 generics with an lapply带有 lapply 的内部 S3 泛型
【发布时间】:2021-10-01 12:30:59
【问题描述】:

我有一个 S3 通用函数,我想成为包的内部部分。如果可能的话,我宁愿不出口它。一个有趣的缺点是lapply 似乎无法找到或使用正确的 S3 方法。有谁知道这种行为背后的原因?下面是一个可重现的示例,其中涉及从我的 github 安装一个虚拟包。

在这种情况下,通用函数是docheck,如果对象是"foo",则返回TRUE,否则返回FALSE

library(remotes)
install_github("jtlandis/SOExample")
#> Skipping install of 'SOExample' from a github remote, the SHA1 (27ab918c) has not changed since last install.
#>   Use `force = TRUE` to force installation
library(SOExample)

foo 函数只是一个带有"foo" 类的NA 对象。

foo
#> function () 
#> structure(NA, class = "foo")
#> <bytecode: 0x0000000015033878>
#> <environment: namespace:SOExample>

fun_success() 只是显示了内部(未导出)S3 函数工作的情况。

fun_success
#> function (x) 
#> {
#>     docheck(x)
#> }
#> <bytecode: 0x0000000013f83100>
#> <environment: namespace:SOExample>

fun_success(foo())
#> [1] TRUE

fun_failure() 调用相同的内部泛型方法,但失败

fun_failure
#> function (x) 
#> {
#>     lapply(list(x), docheck)
#> }
#> <bytecode: 0x0000000015e68df0>
#> <environment: namespace:SOExample>

fun_failure(foo())
#> Error in UseMethod("docheck"): no applicable method for 'docheck' applied to an object of class "foo"

reprex package (v2.0.0) 于 2021 年 7 月 24 日创建

【问题讨论】:

    标签: r oop lapply


    【解决方案1】:

    R 在确保正确注册 S3 方法方面越来越挑剔。注册包通用方法的常规方法是使用 NAMESPACE 文件中的 S3method()。但是,如果您试图保留所有 docheck 未导出,那么您需要自己注册 S3 方法。您可以使用 .S3method() 函数来做到这一点。在你的 R 文件中,添加这一行

    # Existing line...
    # docheck.foo <- function(x) T
    # New line...
    .S3method("docheck", "foo", docheck.foo)
    

    这将允许lapply 找到方法。

    【讨论】:

    • 我很欣赏这个答案,并将它应用到我的包中,因为它解决了这个问题。似乎仍然需要做很多额外的工作。对于lapply 无法找到正确方法的原因还没有很好的解释。也许lapply 在新环境中进行评估?
    猜你喜欢
    • 2020-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多