Чтобы ответить на ваш первый вопрос: вы можете сделать as.character(packageVersion(x))
.
Второй вопрос сложнее: класс S3 определяет свой собственный оператор $
. Я не знаю, почему , но мы здесь.
〉`$.package_version`
function (x, name)
{
name <- pmatch(name, c("major", "minor", "patchlevel"))
x <- unclass(x)
switch(name, major = vapply(x, "[", 0L, 1L), minor = vapply(x,
"[", 0L, 2L), patchlevel = vapply(x, "[", 0L, 3L))
}
<bytecode: 0x7fe3aa8fd000>
<environment: namespace:base>
Для этого может быть веская причина (возможно, генерируется много номеров версий пакетов и кэшируется, и дополнительная экономия места актуальна) но, честно говоря, это кажется слишком умным без веской причины. Код также довольно запутанный - то же самое можно написать гораздо проще.
В частности, использование switch
не нужно и вводит в заблуждение, и работает только из-за счастливого совпадения, потому что name
- это не имя , это целое число (pmatch
возвращает индекс частично совпадающей записи). И, конечно, нет абсолютно никакой причины повторять весь этот vapply
код. Таким образом, следующее делает то же самое, только яснее:
`$.package_version` = function (x, name) {
index = pmatch(name, c("major", "minor", "patchlevel"))
vapply(unclass(x), `[`, integer(1L), index)
}