es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿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:

  1. -methods::setRefClass(…)
  2. -methods::setClass(…)
  3. -methods::assignClassDef(Class, classDef, where)
  4. -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.

Tags:  , , ,

Answer

  1. Avatar for 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ón DrawDistroGenerationClass para incluir un argumento adicional env:

    DrawDistroGenerationClass <- function(in_hourStr, in_data, env = parent.frame()){
      # ...
      me <- methods::setRefClass(
        "Draw",
        fields = list(hourStr = "character",
                      data = "numeric"),
        env = env,
        # ...
      )
      # ...
    }
    

    Por defecto, setRefClass() establece la definición de la clase en el entorno de llamada. Al pasar env = 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() y utils::lockBinding() para desbloquear temporalmente el entorno donde se define la clase de referencia antes y después de llamar a setRefClass(). 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.

Comments are closed.