Я заинтересован в установке новых методов для универсальных функций. Например, допустим, у меня есть новый класс (например, coolClass
). Я мог бы написать оболочку для вычисления log10
этого класса и легко установить метод с помощью следующего кода:
setMethod("Math", c(x="coolClass"),
function(x)
{
op = .Generic[[1]]
switch(op,
`log10` = log10_for_coolClass(x),
stop("Undefined operation")
)
}
)
Однако я не могу понять, как настроить метод для передачи нескольких аргументов. Например, общий метод log
. Запуск getGeneric("log")
показывает следующее:
> getGeneric("log")
standardGeneric for "log" defined from package "base"
belonging to group(s): Math
function (x, ...)
standardGeneric("log", .Primitive("log"))
<bytecode: 0x2f9a958>
<environment: 0x2f937f0>
Methods may be defined for arguments: x
Use showMethods("log") for currently available ones.
Увидев это, я ожидаю, что смогу написать следующее, чтобы иметь возможность передать необязательный аргумент base
.
setMethod("Math", signature(x="coolClass",...),
function(x, ...)
{
op = .Generic[[1]]
switch(op,
`log` = log_for_coolClass(x, ...),
stop("Undefined operation")
)
}
)
Но я получаю следующую ошибку:
Error in matchSignature(signature, fdef, where) :
'...' used in an incorrect context
Пробовал без ...
в signature
получаю другую ошибку:
Error in rematchDefinition(definition, fdef, mnames, fnames, signature) :
methods can add arguments to the generic ‘Math’ only if '...' is an argument to the generic
Что мне кажется странным, учитывая, что журнал getGeneric
показывает ...
в методе.
Любые идеи? Есть ли способ зафиксировать дополнительные аргументы? Я пытаюсь освоиться с методами S4, но не понимаю, как передавать необязательные аргументы. Если это невозможно, я был бы признателен, если бы кто-нибудь объяснил, как работает функция log
, например, учитывая, что функция является частью группы Math
, но принимает несколько аргументов.
Обновить
Любопытно, как отмечено ниже, я могу использовать setMethod
непосредственно на log
со следующим:
setMethod("log", signature(x="big.matrix"),
function(x, base=exp(1))
{
log_for_coolClass(x, base=base)
}
)
Однако это не совсем успокаивает мое любопытство. Например, кажется странным повторяться в коде, если я создаю много новых методов в группе Math
. В идеале это выглядело бы примерно так:
setMethod("Math", c(x="coolClass"),
function(x, base=exp(1))
{
op = .Generic[[1]]
switch(op,
`log10` = log10_for_coolClass(x),
`log` = log_for_coolClass(x, base=base),
stop("Undefined operation")
)
}
)