Я создал пакет, в значительной степени основанный на ссылочных классах. Ответ, который я получил от члена команды CRAN после его отправки, заключался в том, что я не мог использовать <- в пакете (<code>"Please make sure you are not modifying the global environment (f.i. by using <<-"). Оказалось, что это недоразумение (<--
изменяет поле в среде, принадлежащей только эталонному классу, а не глобальную среду), но меня заинтересовали альтернативы <<-
. Я нашел по крайней мере еще один способ присвоения значений полям ссылочного класса, который дает ту же функциональность, что и << - и он "кажется работает", если я использую <code>.self для ссылки на поле и назначаю с помощью <-
вместо <--
. Например, вместо
#' A general purpose linked stack
#'
#' @export Stack
#' @exportClass Stack
Stack <- setRefClass(
Class="Stack",
fields = list(
#' @field size the size of the stack (number of elements in the stack)
m_size = "integer",
#' @field stackNode an envronment containing the current element and the one under
m_stackNode = "ANY"
),
methods = list(
initialize = function (...) {
m_size <<- 0L
},
isEmpty = function() {
if (m_size == 0) {
return(TRUE)
} else {
return(FALSE)
}
},
createEmptyEnvironment = function() {
emptyenv()
},
createNode = function(val, nextNode = NULL) {
node <- new.env(parent=createEmptyEnvironment())
node$element <- val
node$nextNode <- nextNode
node
},
push = function(val) {
"Add an element to the top of the stack"
if(isEmpty()) {
m_stackNode <<- createNode(val)
} else {
m_stackNode <<- createNode(val, m_stackNode)
}
m_size <<- (m_size + 1L)
},
pop = function() {
"Pull the top element from the stack removing it from the stack"
if(!isEmpty()) {
currentNode <- m_stackNode$element
m_stackNode <<- m_stackNode$nextNode
m_size <<- (m_size - 1L)
return(currentNode)
}
},
peek = function() {
"Get the top element from the stack without changing it"
if(!isEmpty()) {
return(m_stackNode$element)
}
},
size = function() {
"Get the current size of the stack"
m_size
}
)
)
я могу сделать это:
#' A general purpose linked stack
#'
#' @export Stack
#' @exportClass Stack
Stack <- setRefClass(
Class="Stack",
fields = list(
#' @field size the size of the stack (number of elements in the stack)
m_size = "integer",
#' @field stackNode an envronment containing the current element and the one under
m_stackNode = "ANY"
),
methods = list(
initialize = function (...) {
.self$m_size <- 0L
},
isEmpty = function() {
if (m_size == 0) {
return(TRUE)
} else {
return(FALSE)
}
},
createEmptyEnvironment = function() {
emptyenv()
},
createNode = function(val, nextNode = NULL) {
node <- new.env(parent=createEmptyEnvironment())
node$element <- val
node$nextNode <- nextNode
node
},
push = function(val) {
"Add an element to the top of the stack"
if(isEmpty()) {
.self$m_stackNode <- createNode(val)
} else {
.self$m_stackNode <- createNode(val, m_stackNode)
}
.self$m_size <- (m_size + 1L)
},
pop = function() {
"Pull the top element from the stack removing it from the stack"
if(!isEmpty()) {
currentNode <- m_stackNode$element
.self$m_stackNode <- m_stackNode$nextNode
.self$m_size <- (m_size - 1L)
return(currentNode)
}
},
peek = function() {
"Get the top element from the stack without changing it"
if(!isEmpty()) {
return(m_stackNode$element)
}
},
size = function() {
"Get the current size of the stack"
m_size
}
)
)
Есть ли проблема с этим (обходным) подходом, всегда ли он будет означать одно и то же при таком использовании? Есть также field(name, value)
, который, кажется, делает то же самое ... это просто разные способы снять шкуру с кошки?