К сожалению, S3 плохо справляется с этой ситуацией. Вы должны искать подходящие функции вручную. Следующие работы, более или менее:
get_defined_function = function (name) {
matches = getAnywhere(name)
# Filter out invisible objects and duplicates
objs = matches$objs[matches$visible & ! matches$dups]
# Filter out non-function objects
funs = objs[vapply(objs, is.function, logical(1L))]
# Filter out function defined in own package.
envs = lapply(funs, environment)
funs = funs[! vapply(envs, identical, logical(1L), topenv())]
funs[1L][[1L]] # Return `NULL` if no function exists.
}
compact.default = function (...) {
# Maybe add error handling for functions not found.
get_defined_function('compact')(...)
}
Использует getAnywhere
, чтобы найти все объекты с именем compact
, о которых R знает. Затем он отфильтровывает те, которые не видны, потому что они не находятся внутри прикрепленных пакетов, и те, которые являются дубликатами (это, вероятно, избыточно, но мы все равно делаем это).
Далее, он отфильтровывает все, что не является функция. И, наконец, он отфильтровывает compact
S3 generi c, который определяет наш собственный пакет. Для этого он сравнивает среду каждой функции со средой пакета (заданной topenv()
).
Это должно сработать, но у него нет правила, какую функцию предпочитать, если существует несколько функций с одинаковым именем определяется в разных местах (сначала он выбирает произвольную единицу), а также не проверяет соответствие сигнатуры функции (это сложно сделать в R, поскольку вызов функции и сопоставление параметров очень гибкие).