2011-11-02 9 views
6

Come posso garantire che quando viene chiamata una funzione non sia consentito catturare le variabili dall'ambiente globale?come isolare una funzione

Vorrei il seguente codice per darmi un errore. Il motivo è perché potrei aver digitato in modo errato z (volevo digitare y).

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

Immagino che la risposta abbia a che fare con gli ambienti, ma non li ho ancora capiti.

C'è un modo per rendere predefinito il comportamento desiderato (ad esempio impostando un'opzione)?

+1

C'è qualche discussione nella notizia del 27 febbraio 2010 sulla home page proto: http://r-proto.googlecode.com. –

+0

@ G.Grothendieck grazie, sembra interessante. Non sono sicuro di avere ancora voglia di scavare in un così grande pacchetto/cambiamento di filosofia. Ma terrò questo a mente quando avrò più esperienza. –

+0

Sono abbastanza sicuro che questo è già stato chiesto qui. – hadley

risposta

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

La funzione non cambia, quindi non è necessario controllarla ogni volta che viene utilizzata. findGlobals è più generale e un po 'più criptico. Qualcosa di simile

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

potuto visitare tutte le funzioni in un ambiente, ma se ci sono diverse funzioni allora forse è il momento di pensare di scrivere un pacchetto (che non è così difficile).

+0

grazie! Sembra una grande funzione. Tuttavia, devi ancora preoccuparti degli ambienti che appare. cioè, se copio e inserisco tutto il codice nel mio post originale e poi eseguo 'checkUsage (temp)' non segnalerà un errore. Ho bisogno di copiare solo la funzione 'temp'. –

+0

vedere 'findGlobals' e le pagine di aiuto per il pacchetto. –

+0

ok lo controllerò. Come posso eseguire checkUsage su tutte le funzioni in ls()? O se è difficile, supponendo che ci siano solo funzioni in uscita da ls(), come posso eseguire checkUsage su tutte loro? Ho provato 'lapply (ls(), FUN = checkUsage)' ma questo non funziona. –

5
environment(temp) = baseenv() 

Vedi anche http://cran.r-project.org/doc/manuals/R-lang.html#Scope-of-variables e ?environment.

+0

Maschera tutte le variabili tranne nell'ambiente di base. Ad esempio, i pacchetti aggiuntivi non sono disponibili all'interno di 'temp'. – kohske

+0

e come dovrei mascherare tutto eccetto 'base' e, ad esempio, il pacchetto' plyr'? –

+0

Non sono sicuro, ma forse 'environment (temp) <- new.env (parent = as.environment (search() [2]))' maschera solo l'ambiente globale. – kohske

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

(sto usando 'divertimento' al posto del nome della funzione 'temp' per chiarezza)

Questo rimuoverà l'ambiente "spazio di lavoro" (.GlobalEnv) dal percorso di ricerca e lasciare tutto altro (ad es. tutti i pacchetti).

+0

grazie! Lo proverò la prossima volta che verrà fuori. –

Problemi correlati