2012-01-25 26 views
6

是否有可能使用env()作爲命名空間的替代品,以及如何在添加功能之前檢查環境是否已經存在?如何在現有環境中添加功能

這涉及到這個問題,和Brendan的建議 How to organize large R programs? 我瞭解德克在這個問題點,但發展有時不切實際把功能包。

編輯:這個想法是模仿跨文件的命名空間,因此能夠獨立加載不同的文件。如果之前已經加載了一個文件,則不需要創建環境,只需添加即可。

感謝想法

編輯:那麼想必下面這段代碼將命名空間的其他語言的等價物: - 在以同樣的方式存在的環境

# how to use environment as namespaces 

# file 1 

# equivalent of 'namespace e' if (!(exists("e") && is.environment(e))) { e <- new.env(parent=baseenv()) } 

e$f1 <- function(x) {1} 


# file 2 
# equivalent of 'namespace e' if (!(exists("e") && is.environment(e))) { e <- new.env(parent=baseenv()) } 

e$f2 <- function(x) {2} 
+3

我將許多*代碼組織到軟件包中,但使用Hadley的'devtools'軟件包將其加載到環境中。這基本上可以實現您所描述的內容,但是如果需要,我還可以創建並重新使用該包。 (換句話說,在開發過程中,我不需要不斷重建軟件包。) – Andrie

回答

2

您可以檢查你將任何其他變量。

e <- new.env() 
exists("e") && is.environment(e) 
5

是的,你可以大部分。每個函數都有一個環境,這就是它尋找其他函數和全局變量的地方。通過使用你自己的環境,你可以完全控制它。

通常功能也分配環境(通過將它們分配給一個名稱),通常這兩個環境是相同的 - 但並不總是。在一個包中,命名空間環境用於兩者,但搜索路徑上的(不同)包環境也具有相同(導出)的函數定義。所以那裏的環境是不同的。

# this will ensure only stats and packages later on the search list are searched for 
# functions from your code (similar to import in a package) 
e <- new.env(parent=as.environment("package:stats")) 

# simple alternative if you want access to everything 
# e <- new.env(parent=globalenv()) 

# Make all functions in "myfile.R" have e as environment 
source("myfile.R", local=e) 

# Or change an existing function to have a new environment: 
e$myfunc <- function(x) sin(x) 
environment(e$myfunc) <- e 

# Alternative one-liner: 
e$myfunc <- local(function(x) sin(x), e) 

# Attach it if you want to be able to call them as usual. 
# Note that this creates a new environment "myenv". 
attach(e, name="myenv") 

# remove all temp objects 
rm(list=ls()) 

# and try your new function: 
myfunc(1:3) 

# Detach when it's time to clean up or reattach an updated version... 
detach("myfile") 

在上面的例子,e對應於命名空間和附接的「myenv」對應於一個包裝環境(如「包:統計」的搜索路徑上)。

4

命名空間環境,因此您可以使用完全相同的機制。由於R使用詞法範圍界定,環境的父親定義了函數將看到的內容(即自由變量是如何被綁定的)。和名字空間一樣,您可以附加環境並查找它們。

所以要建立一個全新的「手動命名空間」,你可以使用類似

e <- new.env(parent=baseenv()) 
# use local(), sys.source(), source() or e$foo <- assignment to populate it, e.g. 
local({ 
    f <- function() { ... } 
    #... 
}, e) 
attach(e, name = "mySuperNamespace") 

現在它被加載和連接,就像一個命名空間 - 這樣你就可以使用f,就像它是在一個命名空間。命名空間使用另一個父級環境來解析導入 - 如果你關心,你也可以這樣做。如果您需要檢查您的酷環境,只需檢查搜索路徑,例如"mySuperNamespace" %in% search()。如果您需要實際的環境,請使用as.environment("mySuperNamespace")

相關問題