Limitar el scope de la variable

Intento escribir una función, lo que limita el scope de las variables R. Por ejemplo,

source("LimitScope.R") y = 0 f = function(){ #Raises an error as y is a global variable x = y } 

Pensé en probar el entorno variable, pero no estaba realmente seguro de cómo hacer esto.

El porque

Enseño R a los estudiantes de licenciatura. En sus primeras prácticas, algunos de ellos siempre olvidan el scope variable, por lo que las funciones enviadas no funcionan. Por ejemplo, siempre obtengo algo así como:

 n = 10 f = function(x){ #Raises an error #as I just source f and test it for a few test cases. return(x*n) } 

Estaba buscando una función rápida que “apague” el scope. Como se puede imaginar, no tiene que ser particularmente robusto, ya que solo se ofrecería para las pocas prácticas.

No estoy seguro de que quiera hacer esto en general, pero la función local() debería ayudar, al igual que la biblioteca codetools .

En tu ejemplo, prueba

 f = local( function() { ... }, baseenv()) 

No hace exactamente lo que quiere, pero debe acercarse más.

Puede forzar una variable para que sea la versión local con esta función:

 get_local <- function(variable) { get(variable, envir = parent.frame(), inherits = FALSE) } 

Compare estos casos

 y <- 0 f <- function() { x <- y } print(f()) # 0 y <- 0 f <- function() { y <- get_local("y") x <- y } print(f()) # Error: 'y' not found 

Dependiendo de lo que esté haciendo, también puede verificar si y era un argumento para f , usando formalArgs o formalArgs .

 g <- function(x, y = TRUE, z = c("foo", "bar"), ...) 0 formalArgs(g) # [1] "x" "y" "z" "..." formals(g) #$x # # #$y #[1] TRUE # #$z #c("foo", "bar") # #$... 

EDITAR: El punto más general de "cómo desactivar el ámbito léxico sin cambiar el contenido de las funciones" es más difícil de resolver. Estoy bastante seguro de que las reglas de scope están bastante arraigadas en R. Una alternativa podría ser usar S-Plus, ya que tiene diferentes reglas de scope .

Puedes verificar si y existe en el entorno global usando exists('y',envir=.GlobalEnv)

Lo que ocasionalmente me pasa es que tengo una pantalla dividida en ESS con un búfer de archivo de código R a la izquierda y el intérprete a la derecha. Pude haber establecido algunos valores en el intérprete mientras depuro el código en el que estoy trabajando en el búfer. Entonces es posible que el código en el buffer accidentalmente refereneces algo que puse en el intepreter. Es difícil detectar el problema a menos que evalúe mi búfer en un intérprete nuevo cada vez, que no es el modo en que funciona ESS por defecto.

Si este es el tipo de problema que está viendo con frecuencia, una rm (list = ls (envir = .GlobalEnv)) en la fuente puede ayudar, pero eso por supuesto crea otros problemas, como borrar cualquier cosa que estén usando para mantener estado mientras se depura, etc.