我知道methods()
,它返回给定类的所有方法。假设我有 x
我想知道当我调用 foo(x)
时会调用什么方法.是否有可以做到这一点的oneliner或包裹?
我能想到的最短的是:
sapply(class(x), function(y) try(getS3method('foo', y), silent = TRUE))
然后检查结果的类...但是没有内置的吗?
更新
完整的一个类轮将是:
fm <- function (x, method) {
cls <- c(class(x), 'default')
results <- lapply(cls, function(y) try(getS3method(method, y), silent = TRUE))
Find(function (x) class(x) != 'try-error', results)
}
这适用于大多数事情,但请注意它可能会因一些复杂的对象而失败。例如,根据
?S3Methods
, 调用foo
在 matrix(1:4, 2, 2)
会尝试foo.matrix
,然后 foo.numeric
,然后 foo.default
;而这段代码只会寻找 foo.matrix
和 foo.default
.
最佳答案
findMethod
下面定义的不是单行代码,但它的主体只有 4 行代码(如果我们要求将泛型作为字符串传递,它可以减少到 3 行代码)。它将返回一个字符串,表示将由输入泛型在给定泛型及其参数的情况下分派(dispatch)的方法的名称。 (如果您想返回方法本身,请将 findMethod
正文的最后一行替换为 get(X(...))
。)在内部,它创建一个泛型 X 和一个对应于输入泛型的每个方法的 X 方法,这样每个 X 方法返回将要运行的输入泛型方法的名称。 X 泛型及其方法都在 findMethod
中创建。函数,所以它们在 findMethod
时消失退出。为了得到结果,我们只需运行 X 并将输入参数作为 findMethod
的最后一行。功能体。
findMethod <- function(generic, ...) {
ch <- deparse(substitute(generic))
f <- X <- function(x, ...) UseMethod("X")
for(m in methods(ch)) assign(sub(ch, "X", m, fixed = TRUE), "body<-"(f, value = m))
X(...)
}
现在测试一下。 (请注意,问题中的单行在其中几个测试中失败并出现错误,但
findMethod
给出了预期的结果。)findMethod(as.ts, iris)
## [1] "as.ts.default"
findMethod(print, iris)
## [1] "print.data.frame"
findMethod(print, Sys.time())
## [1] "print.POSIXct"
findMethod(print, 22)
## [1] "print.default"
# in this example it looks at 2nd component of class vector as no print.ordered exists
class(ordered(3))
## [1] "ordered" "factor"
findMethod(print, ordered(3))
## [1] "print.factor"
findMethod(`[`, BOD, 1:2, "Time")
## [1] "[.data.frame"
关于R:如何找到对象会调用什么 S3 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42738851/