2011-11-02 27 views
6

¿Cómo puedo asegurarme de que cuando se llama a una función no se permite tomar variables del entorno global?cómo aislar una función

Me gustaría que el siguiente código me diera un error. La razón es porque podría haber escrito mal z (quería escribir y).

z <- 10 
temp <- function(x,y) { 
     y <- y + 2 
     return(x+z) 
} 
> temp(2,1) 
[1] 12 

supongo que la respuesta tiene que ver con los ambientes, pero no lo han entendido los todavía.

¿Hay alguna manera de hacer que mi comportamiento deseado sea el predeterminado (por ejemplo, configurando una opción)?

+1

Existe un debate en la noticia de 27 de febrero de 2010 en la página de inicio de proto: http://r-proto.googlecode.com. –

+0

@ G.Grothendieck gracias, eso parece interesante. No estoy seguro de si todavía tengo ganas de profundizar en un paquete/cambio de filosofía tan grande. Pero lo tendré en cuenta una vez que tenga más experiencia. –

+0

Estoy bastante seguro de que esto ya se ha preguntado aquí. – hadley

Respuesta

4
> library(codetools) 
> checkUsage(temp) 
<anonymous>: no visible binding for global variable 'z' 

La función no cambia, por lo que no es necesario verificarla cada vez que se utiliza. findGlobals es más general, y un poco más críptico. Algo así como

Filter(Negate(is.null), eapply(.GlobalEnv, function(elt) { 
    if (is.function(elt)) 
     findGlobals(elt) 
})) 

podría visitar todas las funciones en un entorno, pero si hay varias funciones, entonces quizás es el momento de pensar en escribir un paquete (que no es tan duro).

+0

gracias! Eso parece una gran función. Sin embargo, todavía tiene que preocuparse por los entornos que aparece. es decir, si copio e inserto todo el código en mi publicación original y luego ejecuto 'checkUsage (temp)' no se informará un error. Necesito copiar solo la función 'temp'. –

+0

ver 'findGlobals' y las páginas de ayuda para el paquete. –

+0

bien, lo comprobaré. ¿Cómo puedo ejecutar checkUsage en todas las funciones en ls()? O si eso es difícil, suponiendo que solo hay funciones generadas por ls(), ¿cómo puedo ejecutar checkUsage en todas ellas? Intenté 'lapply (ls(), FUN = checkUsage)' pero eso no funciona. –

5
environment(temp) = baseenv() 

Ver también http://cran.r-project.org/doc/manuals/R-lang.html#Scope-of-variables y ?environment.

+0

Enmascara todas las variables excepto en el entorno base. es decir, los paquetes complementarios no están disponibles dentro del 'temp'. – kohske

+0

y cómo iba a enmascarar todo excepto 'base' y, por ejemplo, el paquete' plyr' –

+0

No estoy seguro, pero tal vez 'environment (temp) <- new.env (parent = as.environment (search() [2]))' enmascara solo el entorno global. – kohske

1
environment(fun) = parent.env(environment(fun)) 

(estoy usando 'diversión' en lugar de su nombre de la función 'temp' para mayor claridad)

Esto eliminará el medio ambiente "espacio de trabajo" (.GlobalEnv) de la ruta de búsqueda y dejar todo else (por ejemplo, todos los paquetes).

+0

¡gracias! Voy a probar esto la próxima vez que salga. –

Cuestiones relacionadas