【问题标题】:How to define an S3 generic with the same name as a primitive function?如何定义与原始函数同名的 S3 泛型?
【发布时间】:2020-12-28 02:47:09
【问题描述】:

我在 R 包中有一个类 myclass,我想为其定义一个方法 as.raw,因此与原始函数 as.raw() 同名。如果构造函数、泛型和方法定义如下...

new_obj <- function(n) structure(n, class = "myclass") # constructor
as.raw <- function(obj) UseMethod("as.raw") # generic
as.raw.myclass <- function(obj) obj + 1 # method (dummy example here)

...然后R CMD check 导致:

Warning: declared S3 method 'as.raw.myclass' not found
See section ‘Generic functions and methods’ in the ‘Writing R
Extensions’ manual.

如果泛型是as_raw 而不是as.raw,那么没有问题,所以我假设这是因为原始函数as.raw 已经存在。是否可以通过将as.raw 定义为泛型来“重载”as.raw(或者是否需要使用不同的名称?)?

更新:NAMESPACE 包含

export("as.raw") # export the generic
S3method("as.raw", "myclass") # export the method

This 似乎有些相关,但dimnames 有一个泛型,所以有一个解决方案(只是不要定义你自己的泛型),而上面不清楚(对我来说)解决方案是什么。

【问题讨论】:

  • 此问题可能重复:stackoverflow.com/questions/59056308/…stackoverflow.com/questions/42986174/…。您需要隐藏基本函数,因为它不是通用的。
  • 谢谢,这很有趣。我尝试了两个版本,首先是setGeneric("as.raw"),然后按照您发布的链接中的建议定义as.raw.default &lt;- function(x) base::as.raw(x)。我仍然收到同样的警告。会不会是 R 对 as.raw.myclass 中的两个点感到困惑,因此找不到方法?
  • 你是在导出这些函数吗?您的 NAMESPACE 文件是什么样的?这两个点应该无关紧要。
  • 我更新了帖子以显示 NAMESPACE 包含的内容。
  • 如果我也像您发布的第二个链接那样通过S3method("as.raw", "default") 导出默认方法,我会收到两次警告,一次是as.raw.myclass,一次是as.raw.default

标签: r generics methods


【解决方案1】:

这里的问题似乎是as.raw 是一个原始函数(is.primitive(as.raw))。从?setGeneric 帮助页面,它说

许多基本的 R 函数被特别实现为原始函数,直接在底层 C 代码中进行计算,而不是通过计算 R 语言定义。大多数都具有隐式泛型(请参阅implicitGeneric),并在其上定义方法(包括组方法)后立即变为泛型。

根据?InternalMethods 帮助页面,as.raw 是这些原始泛型之一。所以在这种情况下,您只需要导出 S3 方法。并且您要确保您的函数签名与现有原始函数的签名匹配。

所以如果我有以下 R 代码

new_obj <- function(n) structure(n, class = "myclass")
as.raw.myclass <- function(x) x + 1

和一个 NAMESPACE 文件

S3method(as.raw,myclass)
export(new_obj)

然后这会为我通过包检查(在 R 4.0.2 上)。我可以运行代码

as.raw(new_obj(4))
# [1] 5
# attr(,"class")
# [1] "myclass"

所以在这种特殊情况下,您需要将as.raw &lt;- function(obj) UseMethod("as.raw") 部分去掉。

【讨论】:

  • ... 我已经尝试过了,但错过了,然后方法的参数必须匹配 as.raw 之一,所以 x 而不是 obj。谢谢,现在可以了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-30
  • 1970-01-01
  • 2019-11-01
相关资源
最近更新 更多