`NextMethod()`的内部工作原理

Eva*_*Aad 11 oop methods inheritance r parametric-polymorphism

我想弄清楚它是如何NextMethod()工作的.我在S3类系统中找到的最详细的解释是在Chambers&Hastie(edts.)的S中的统计模型(1993,Chapman&Hall)中,但是我发现有关NextMethod调用的部分有点模糊.以下是我试图理解的相关段落(第268-269页).

现在转向由于调用而调用的方法 NextMethod(),这些方法就好像它们是通过特殊调用从前一个方法调用的.对继承方法的调用中的参数在数量,顺序和实际参数名称上与在调用当前方法时的参数相同(因此,在对泛型的调用中).但是,参数的表达式是当前方法的相应形式参数的名称.例如,假设表达式print(ratings)已调用该方法print.ordered().当这个方法调用时 NextMethod(),这相当于对print.factor()表单的调用print.factor(x),这里xx框架中的 print.ordered().如果多个参数与形式参数" ..." 匹配,那么这些参数在对继承方法y特殊名称" ..1"," ..2"等的调用中表示.评估者识别这些名称并对其进行适当处理(参见第476页的示例).

这个相当微妙的定义的存在是为了确保S中函数调用的语义尽可能干净地使用方法(比较Becker,Chambers和Wilks的The New S Language,第354页).特别是:

  • 参数从当前方法传递到继承方法,NextMethod()并调用它们当前的当前值.
  • 懒惰的评估继续有效; 未经评估的论点仍未得到评估.
  • 继承的方法中缺少缺少的参数.
  • 通过 " ..."形式参数传递的参数以正确的参数名称到达.
  • 框架中与调用中的实际参数不对应的对象将不会传递给继承的方法."

就参数而言,继承过程基本上是透明的.

我觉得困惑的两点是:

  1. 什么是"当前方法",什么是"以前的方法"?
  2. "调用继承方法的参数","参数的表达式"和"当前方法的相应形式参数的名称"之间有什么区别?

一般来说,如果有人可以请以一种清醒的方式重述上述段落中的描述,我会很感激.

ags*_*udy 10

很难通过所有这篇文章,但我认为这个小例子可以帮助神秘化Next Next方法调度.

我创建了一个具有2个类属性(继承)'first'和'second'的对象.

x <- 1
attr(x,'class') <- c('first','second')
Run Code Online (Sandbox Code Playgroud)

然后我创建了一个generic方法Cat来打印我的对象

Cate <- function(x,...)UseMethod('Cate')
Run Code Online (Sandbox Code Playgroud)

Cate为每个类定义方法.

Cate.first <- function(x,...){
  print(match.call())
  print(paste('first:',x))
  print('---------------------')
  NextMethod()                ## This will call Cate.second
}

Cate.second <- function(x,y){
  print(match.call())
  print(paste('second:',x,y))
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以Cate使用此示例检查呼叫:

 Cate(x,1:3)
Cate.first(x = x, 1:3)
[1] "first: 1"
[1] "---------------------"
Cate.second(x = x, y = 1:3)  
[1] "second: 1 1" "second: 1 2" "second: 1 3"
Run Code Online (Sandbox Code Playgroud)
  • 对于Cate.second,前一个方法是Cate.first
  • 参数x和y从当前方法向下传递给继承的方法,并在调用NextMethod()时使用它们的当前值.
  • 通过"..."形式参数传递的参数y带有正确的参数名称 Cate.second(x = x, y = 1:3)


G. *_*eck 6

考虑下面这个例子,其中泛型函数f被调用,它调用f.ordered,然后使用NextMethod,f.ordered调用f.factor:

f <- function(x) UseMethod("f")  # generic
f.ordered <- function(x) { x <- x[-1]; NextMethod() }
f.factor <- function(x) x # inherited method
x <- ordered(c("a", "b", "c"))

class(x)
## [1] "ordered" "factor" 

f(x)
## [1] b c
## Levels: a < b < c
Run Code Online (Sandbox Code Playgroud)

现在考虑原始文本:

现在转到调用NextMethod()时调用的方法,这些方法就好像它们是通过特殊调用从前一个方法调用的.

这里f调用f.ordered哪些调用,f.factor因此"调用NextMethod"调用f.factor的方法是" 前一个方法" f.ordered.

对继承方法的调用中的参数在数量,顺序和实际参数名称上与在调用当前方法时的参数相同(因此,在对泛型的调用中).但是,参数的表达式是当前方法的相应形式参数的名称.例如,假设表达式print(ratings)已经调用了print.ordered()方法.当此方法调用NextMethod()时,这相当于调用print.factor(x)形式的print.factor(),其中x是print.ordered()框架中的x

现在我们切换透视图,我们坐在那里,f.ordered所以现在f.ordered 是当前的方法,并且f.factor是继承的方法.

f.ordered调用NextMethod()特殊调用时,构造为调用f.factor其参数与传递给f.ordered泛型的参数相同,f 除了它们引用参数的版本f.ordered(这在这里有所不同,因为f.ordered在调用之前更改了参数 f.factor.