UseMethod 是一个比较特殊的函数,它的行为和其它的函数调用有点差异。
该函数的调用语法是
UseMethod(generic, object),其中 generic是
泛型函数的名字, object 用于决定哪一个方法将会被采用的对象。
UseMethod 仅可在函数内部被调用。
S 定义里面的 UseMethod 含有一个额外的参数 ...,
该参数可能会影响随后被调用方法的一些默认值。
R 在 UseMethod 有多于两个参数时给出警告,并且
忽略多余的参数。
UseMethod通过两种方式改变求值模式。第一种方式是,当它被调用时,它决定下一个
被调用的方法(函数),然后利用当前求值环境调用该函数;
这个过程将会被简单描述。第二种方式是,UseMethod 会改变求值环境,
但不会返回对函数调用的控制。这就意味着,任何在UseMethod调用后面出现的语句
肯定不会被执行。
当UseMethod被调用时,泛型函数是调用UseMethod时的指定值。
准备分发的对象要么是当前函数的第一个参数要么是给定的第二个参数。
参数的类可以被确定,它的一个元素结合泛型函数的名字可用来确定适当的方法。
因此,如果泛型的名字是 foo 而对象的类是 "bar",那么
R 将会搜索一个名为 foo.bar 的方法。如果不存在这样的方法,
那么上面描述的继承机制可用来查找适当的方法。
一旦一个方法已经被确定,R 能以一种特别的方式调用它。
和创建新的求值环境不同的是,
R 使用当前函数调用(泛型的调用)的环境。
任何在调用 UseMethod 前的赋值或求值都将有效。
用于调用泛型函数的参数会再次匹配所选方法的形式参数。
当一个方法被调用时,所使用的参数在参数数目和名字上和调用泛型时采用的都是 一样的。利用R里面标准的参数匹配规则,这些参数会和所调用方法的参数比较。 但第一个参数会被求值。
调用 UseMethod 的一个后果是把一些特殊对象放在
求值框架中。它们是 .Class,
.Generic 和 .Method。这些特殊对象被R用来
处理方法分发和继承。 .Class 是对象的类,
.Generic 是泛型函数的名字以及
.Method 是当前调用的方法的名字。
如果方法通过内部接口调用,可能还会有一个称为.Group的对象。
这些将在 Group methods 部分描述。在初始调用 UseMethod 后,
这些特别的变量,不是对象自身,控制了随后方法的选择。
方法的主体然后以标准的方式求值。特别是,主体中的变量搜索方式遵循
为方法设置的规则。因此如果一个方法有相关的环境,那么该环境将会被使用。
结果是,我们用方法调用代替了泛型调用。
泛型框架下的局部赋值会传递给方法调用。
不过,这种特性的使用一般不被推崇。
需要了解的是,控制不会返回给泛型因此调用
UseMethod 后的任何表达式都不会被执行。
泛型的任何可求值参数在调用
UseMethod 前保留其可求值特性。
泛型调用过程中的参数会使用标准的参数匹配机制 在方法参数中再次匹配。第一个参数(也是一个对象) 将被求值。
如果没有提供UseMethod的第一个参数,则假定是当前函数的名字。
如果UseMethod有两个参数,则第一个是方法名,第二个假定是方法分发时
参考的对象。它将会被求值使得可以确定必须的方法。在这种情况下,
泛型调用的第一个参数不会被求值并会被抛弃。
没有办法改变方法调用中的其它参数,它们似乎仍在泛型调用中。
这和另外一种方法调用中的参数可以改变的 NextMethod
函数形成鲜明对比。