2011-11-02 73 views
6

如何確保函數被調用時不允許從全局環境中獲取變量?如何隔離函數

我想下面的代碼給我一個錯誤。原因是因爲我可能錯誤地輸入了z(我想輸入y)。

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

我猜測答案與環境有關,但我還沒有理解這些。

有沒有辦法使我想要的行爲默認(例如通過設置選項)?

+1

在2010年2月27日關於proto主頁的新聞中有一些討論:http://r-proto.googlecode.com。 –

+0

@ G.Grothendieck謝謝你,這看起來很有趣。我不確定我是否想要深入挖掘這麼大的一攬子/哲學變革。但是,一旦我獲得更多的經驗,我會牢記這一點。 –

+0

我很確定這已經在這裏問過了。 – hadley

回答

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

功能不會改變,因此沒有必要它每次使用時進行檢查。 findGlobals更普遍,更隱蔽一點。像

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

事情就可以訪問所有功能於一身的環境,但是如果有幾個功能,那麼也許是時候考慮寫一個包(它並不難)。

+0

謝謝!這看起來很棒。但是,您仍然需要擔心它出現的環境。即如果我複製並在我的原始帖子中插入所有代碼,然後運行'checkUsage(temp)',它不會報告錯誤。我只需要複製'temp'函數。 –

+0

參見'findGlobals'和包的幫助頁面。 –

+0

好的,我會檢查一下。我如何在ls()中的所有函數上運行checkUsage?或者,如果這很困難,假設只有ls()輸出的函數,我怎麼才能在所有的函數上運行checkUsage?我嘗試過'lapply(ls(),FUN = checkUsage)',但這不起作用。 –

5
environment(temp) = baseenv() 

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

+0

它將屏蔽基本環境中的所有變量。即附加軟件包在「temp」中不可用。 – kohske

+0

以及如何屏蔽除「base」和「plyr」包之外的所有內容? –

+0

不確定,但也許'環境(臨時)< - new.env(parent = as.environment(search()[2]))'將只屏蔽全局環境。 – kohske

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

(我使用替代你的函數名稱「臨時」爲清楚「樂趣」)

這會從搜索路徑中刪除「工作區」環境(.GlobalEnv),並放棄一切其他(例如所有包)。

+0

謝謝!我會在下次出現時嘗試這個。 –