如何为内部泛型的方法添加其他参数?

max*_*eld 9 oop methods inheritance r internal

我想为我的类myClass实现内部泛型[<-(〜help(Extract))的inset方法.在将实际插入传递给[<-via 之前,此方法应该运行一堆测试NextMethod().

我明白那个:

  • 任何方法必须至少包括泛型的参数(我认为我的)
  • NextMethod()呼叫通常不需要任何参数(尽管手动提供他们似乎并没有帮助其一).

这是我的代表:

x <- c(1,2)
class(x) <- c("myClass", "numeric")

`[<-.myClass` <- function(x, i, j, value, foo = TRUE, ...) {
  if (foo) {
    stop("'foo' must be false!")
  }
  NextMethod()
}

x[1] <- 3  # this errors out with *expected* error message, so dispatch works
x[1, foo = FALSE] <- 3  # this fails with "incorrect number of subscripts
Run Code Online (Sandbox Code Playgroud)

似乎正在发生的事情是,它NextMethod() 传递foo给内部泛型[<-,这会foo导致另一个索引出错,并因此输出错误(因为,在这种情况下,x没有第二个维度可以索引).

我也尝试明确地提供参数no NextMethod(),但这也失败了(参见break下面的代表).

如何避免NextMethod()使用我的方法的其他参数窒息?

(额外奖励:有没有人知道建立内部仿制药方法的良好资源?@Hadleys adv-r在此问题上有点短缺).


具有显式参数的Reprex:

x <- c(1,2)
class(x) <- c("myClass", "numeric")

`[<-.myClass` <- function(x, i = NULL, j = NULL, value, foo = TRUE, ...) {
  if (foo) {
    stop("'foo' must be false!")
  }
  NextMethod(generic = "`[<-`", object = x, i = i, j = j, value = value, ...)
}

x[1] <- 3  # this errors out with expected error message, so dispatch works
x[1, foo = FALSE] <- 3  # this fails with "incorrect number of subscripts
Run Code Online (Sandbox Code Playgroud)

had*_*ley 5

除了剥离该类(它构成的副本x)之外,我看不到任何简便的方法

`[<-.myClass` <- function(x, i, value, ..., foo = TRUE) {
  if (foo) {
    cat("hi!")
    x
  } else {
    class_x <- class(x)
    x <- unclass(x)
    x[i] <- value
    class(x) <- class_x
    x
  }
}

x <- structure(1:2, class = "myClass")
x[1] <- 3
#> hi!

x[1, foo = FALSE] <- 3
x
#> [1] 3 2
#> attr(,"class")
#> [1] "myClass"
Run Code Online (Sandbox Code Playgroud)

这不是一个通用的方法-这是唯一需要的[[<-等等,因为它们不使用的参数匹配规则的规则:

请注意,这些操作不以标准方式匹配其索引参数:参数名称将被忽略,仅使用位置匹配。因此m[j = 2, i = 1]等于m[2, 1]和不等于m[1, 2]

(来自的“参数匹配”部分?`[`

这意味着您x[1, foo = FALSE]等于x[1, FALSE],然后由于x不是矩阵,您会收到一条错误消息。

无效的方法:

  • 提供额外的参数给NextMethod():这只能增加参数数量,而不能减少参数数量

  • foo与解除绑定rm(foo):这会导致有关undefined的错误foo

  • 替换foo为缺少的符号:这将导致错误,该错误foo没有提供默认参数。