¿Cómo puedo resolver “no se pueden añadir enlaces a un ambiente bloqueado” al trabajar con setRefClass en R?
Tengo una función en R de la siguiente manera
DrawDistroGenerationClass <- function(in_hourStr, in_data){
me <- methods::setRefClass(
## Define the environment where this list is defined so
## that I can refer to it later.
"Draw",
fields = list(hourStr = "character",
data = "numeric"),
methods = list(
getModel = function(){
return("Draw Distro")
},
getName = function(){
return(hourStr)
},
generateHoursFromStorage = function(strName){
indSelect <- stats::runif(1, min = 1, max = length(data))
componentLife <- data[indSelect]
return(componentLife)
}
)
)
newMe <- me$new(hourStr = in_hourStr, data = in_data)
return(newMe)
}
La prueba se ve así…
test_that("test Time2Repair-DrawDistroHoursGenerationClass", {
distroHoursGenerationClass <- DrawDistroHoursGenerationClass("test", c(0.0, 1.0, 2.0, 3.0))
testthat::expect_equal(distroHoursGenerationClass$getModel(), "Draw Distro")
testthat::expect_equal(distroHoursGenerationClass$getName(), "test")
testthat::expect_true(is.numeric(distroHoursGenerationClass$generateHoursFromStorage("test")))
}
)
Con el propósito de poder llamar a la función DrawDistroGenerationClass con una etiqueta y un conjunto de valores, y generar una función que seleccionará aleatoriamente uno de esos valores cada vez que la llame.
La función funciona, pero dentro de mi proyecto de R tengo una prueba unitaria (testthat) para esta función, y cuando ejecuto R cmd obtengo:
- -methods::setRefClass(…)
- -methods::setClass(…)
- -methods::assignClassDef(Class, classDef, where)
- -base::assign(mname, def, where)
“Error en assign(mname, def, where): no se pueden agregar enlaces a un entorno bloqueado”.
No tengo idea de por qué se está produciendo este problema.
Prefiero no hacer que mis variables de entrada sean globales (ya que podrían entrar en conflicto con otras clases) y estoy usando el método setRefClass aquí para poder hacer muchas versiones independientes de esta función.
davy.ai
El mensaje de error “no se pueden agregar asignaciones a un entorno bloqueado” sugiere que estás intentando modificar un entorno bloqueado asignándole un nuevo objeto. En este caso, parece que el problema está relacionado con el uso de
methods::setRefClass()
para definir una clase de referencia.Una solución potencial a este problema es pasar el entorno donde se debe definir la clase de referencia como argumento a
setRefClass()
. Por ejemplo, podrías modificar tu funciónDrawDistroGenerationClass
para incluir un argumento adicionalenv
:Por defecto,
setRefClass()
establece la definición de la clase en el entorno de llamada. Al pasarenv = parent.frame()
o un entorno explícito donde se debe definir la clase, la función ya no intentará modificar un entorno bloqueado.Alternativamente, podrías utilizar
utils::unlockBinding()
yutils::lockBinding()
para desbloquear temporalmente el entorno donde se define la clase de referencia antes y después de llamar asetRefClass()
. Sin embargo, esto podría introducir efectos secundarios no deseados y generalmente no se recomienda a menos que tengas una buena razón para hacerlo.