#r #reference-class
#r #ссылочный класс
Вопрос:
Я работаю со ссылочным классом с несколькими десятками полей. Я настроил initialize()
метод, который принимает объект list. В то время как некоторые поля зависят от дальнейших вычислений из элементов списка, большинство полей назначаются непосредственно из элементов списка как таковых:
fieldA <<- list$A
fieldB <<- list$B
Я подумал, что было бы неплохо немного автоматизировать это. Приведу пример в псевдокоде R (этот пример, очевидно, не сработает):
for (field in c('A', 'B', 'C', 'D'))
field <<- list[[field]]
Я попытался выполнить несколько конечных запусков вокруг <<-
, например, делая что-то вроде:
for field in c('A', 'B', 'C', 'D'))
do.call('<<-' c(field, list[[field]]))
но нет кости.
Я предполагаю, что такого рода поведение просто невозможно в текущем воплощении ссылочных классов, но подумал, что, возможно, стоит посмотреть, знает ли кто-нибудь в SO land о лучшем способе сделать это.
Ответ №1:
Используйте .self
для указания экземпляра и выбора полей с помощью [[
. Я не уверен на 100% (но кто вообще уверен?) это [[
строго законно. Я добавил значения по умолчанию в lst
, поэтому оно работает при вызове как C$new()
, неявное предположение в S4, которое, похоже, сработает аналогичным образом с ссылочными классами.
C <- setRefClass("C",
fields=list(a="numeric", b="numeric", c="character"),
methods=list(
initialize=function(..., lst=list(a=numeric(), b=numeric(), c=character())
{
directflds <- c("a", "b")
for (elt in directflds)
.self[[elt]] <- lst[[elt]]
.self$c <- as.character(lst[["c"]])
.self
}))
c <- C$new(lst=list(a=1, b=2, c=3))
Или оставьте возможность передавать список или сами элементы пользователю с
B <- setRefClass("B",
fields=list(a="numeric", b="numeric", c="character"),
methods=list(
initialize=function(..., c=character()) {
callSuper(...)
.self$c <- as.character(c)
.self
}))
b0 <- B$new(a=1, b=2, c=3)
b1 <- do.call(B$new, list(a=1, b=2, c=3))
Это также кажется более терпимым к пропуску некоторых значений при вызове new()
.