То, что вы видите здесь, является частью того, как работает диспетчеризация метода S4. Фактически, .Generic
является частью механизма отправки метода R .
Кстати, пакет rlang - это красная сельдь: проблема возникает исключительно из-за использования S4 компанией Biobase .
Но в более общем случае ваша стратегия разрешения может потерпеть неудачу в других ситуациях, потому что существуют другие (хотя и редко) причины, по которым пакеты могут определять функции в отдельной среде. Причиной этого обычно является определение замыкания по некоторой переменной.
Например, обычно невозможно изменить переменные, определенные внутри пакета на уровне пространства имен, поскольку пространство имен блокируется при загрузке. Есть несколько способов обойти это. Простой способ, если пакету нужна функция с состоянием, - определить эту функцию внутри среды. Например, вы можете определить функцию counter
, которая увеличивает ее счет при каждом вызове, следующим образом:
counter = local({
current = 0L
function () {
current <<- current + 1L
current
}
})
local
определяет среду, в которую обернута функция.
Кому чтобы справиться с такой ситуацией, вместо этого вам следует перебирать родительские среды, пока не найдете среду пространства имен. Но есть более простое решение, потому что R уже предоставляет функцию для поиска среды пространства имен для данной среды (путем выполнения указанной итерации):
pkgparent = function (fun) {
nsenv = topenv(environment(fun))
environmentName(nsenv)
}