R S3类和名称消歧

  • 本文关键字:S3 r
  • 更新时间 :
  • 英文 :


类似于S4类的这个主题,我想知道S3类的解决方法和冲突预防。

让我举个例子。我创建了两个包:pkga和pkgb。它们碰巧都有一个S3类构造函数,返回一个类名称相同的对象myclass

#' @export
myclass_instance <- function() {
structure(list(name = "pkga"), class = c("myclass"))
}

#' @export
whatever <- function(obj) {
UseMethod("whatever", obj)
}
#' @export
whatever.default <- function(obj) {
print("pkga::whatever.default")
}
#' @export
whatever.myclass <- function(obj) {
print("pkga::whatever.myclass")
}

和pkgb

#' @export
myclass_instance <- function() {
structure(list(name = "pkgb"), class = c("myclass"))
}

#' @export
whatever <- function(obj) {
UseMethod("whatever", obj)
}

#' @export
whatever.default <- function(obj) {
print("pkgb::whatever.default")
}
#' @export
whatever.myclass <- function(obj) {
print("pkgb::whatever.myclass")
}

现在,如果我安装了两个包,并尝试以下操作:

> aobj<-pkga::myclass_instance()
> pkga::whatever(aobj)
[1] "pkga::whatever.myclass"
> pkga::whatever(3)
[1] "pkga::whatever.default"

这些都是正确的。但是,如果我从pkgb创建一个对象,然后将其传递给pkga::whatever,它将不会像我期望的那样应用默认值(它们是两个完全不相关的类,恰好具有相同的名称),因为解析只对名称

进行处理。
> bobj<-pkgb::myclass_instance()
> pkga::whatever(bobj)
[1] "pkga::whatever.myclass"

如果两个不相关的库碰巧具有相同的类名,并且泛型名碰巧冲突,则会产生奇怪的效果。虽然这是一种罕见且不太可能发生的情况,但从正式的角度来看,我一点也不喜欢它,所以我想知道是否有一种方法可以防止这种情况的发生,比在类名前加上包名更好,例如

#' @export
myclass_instance <- function() {
structure(list(name = "pkga"), class = c("pkga::myclass"))
}

#' @export
whatever <- function(obj) {
UseMethod("whatever", obj)
}
#' @export
whatever.default <- function(obj) {
print("pkga::whatever.default")
}
#' @export
`whatever.pkga::myclass` <- function(obj) {
print("pkga::whatever.myclass")
}

和类似的pkgb。

包a和包b使用不同的命名空间。S3的构建是非正式的,所以解决这个问题的唯一方法是使用包名前缀(即pkg::whatever)。

解决这个问题需要一定程度的特异性,这是R中所缺乏的(除了显式前缀)。根据R Packages的这一章,这是一个已知的现象。

相关内容

  • 没有找到相关文章

最新更新