Я пытаюсь реализовать разные версии метода, которые имеют схожие, но разные требования к входным данным.Исходя из языков со статической и строгой типизацией, я пытаюсь написать эти методы таким образом, чтобы свести к минимуму возможность для целевых пользователей (это для пакета) использовать методы непреднамеренными способами.Разные версии метода имеют разное количество параметров, и я обнаружил, что поддержка версий метода с двумя или более параметрами позволяет вводить бессмысленную версию в версию метода, которая ожидает только один параметр.Вот тривиальный пример:
setGeneric(
"foo",
function(a, b) {
standardGeneric("foo")
})
setMethod(
"foo",
signature(a = "numeric"),
function(a) {
abs(a)
})
setMethod(
"foo",
signature(a = "numeric", b = "numeric"),
function(a, b) {
abs(c(a, b))
})
Он работает, как и ожидалось, со следующими входными данными (некоторые действительны, некоторые нет, и выдают ошибки, как и должны):
> foo(-1)
[1] 1
> foo(-1, -2)
[1] 1 2
> foo("cat")
Error in (function (classes, fdef, mtable) :
unable to find an inherited method for function ‘foo’ for signature ‘"character", "missing"’
> foo()
Error in (function (classes, fdef, mtable) :
unable to find an inherited method for function ‘foo’ for signature ‘"missing", "missing"’
> foo(-1, -2, "cat")
Error in foo(-1, -2, "cat") : unused argument ("cat")
Но тогда естьэто один из сценариев, в котором он не ведет себя так, как это должно быть приемлемо:
> foo(-1, "cat")
[1] 1
Он вызывает сигнатуру первого метода и игнорирует второй параметр.Это потенциально серьезная логическая ошибка для пользователей, которая является проблемой для меня, потому что мои целевые пользователи не являются компьютерными учеными;большинство из них не понимают, что такое логические ошибки, насколько они опасны или как их отслеживать. Есть ли способ в R настроить методы так, чтобы последний пример foo(-1, "cat")
выдавал ошибку, а не создавал у пользователя впечатление, что все в порядке?
Примечание,что в то время как различные версии методов, над которыми я работаю, фундаментально связаны, фактические реализации для каждого из них очень разные.Я мог бы использовать функции с необязательными аргументами, но это потребовало бы нескольких проверок для запуска совершенно разных больших кусков кода.Я надеялся избежать этого, потому что это не особенно чисто или элегантно.