2015-04-25 42 views
1

這可能看起來像一個奇怪的問題,但我確實有一個用例,我試圖弄清楚。如何在加載後將函數附加到我的包名稱空間中?

假設我正在編寫一個包,並且我有一個函數允許用戶別名到別的地方 - 用戶提供函數的名稱。我想知道實現這個目標的最佳方法是什麼?

#' @export 
foo <- function() "Hello" 
#' @export 
addAlias <- function(x) assign(x, foo, envir = globalenv()) 

這是我想要得到的行爲 - 現在,用戶可以調用addAlias("bar"),然後,如果他所說bar()這將是,如果他叫我的功能。

顯然這不是一個很好的解決方案,因爲它分配給全球環境。有沒有人有什麼反饋意見是最好的方式來做到這一點?有幾個方法我試過:

1分配給globalenv

就像我的例子顯示。這似乎工作。

2.分配到包的環境

addAlias <- function(x) assign(x, foo, as.environment("package:mypackage")) 

這一段偉大的工作,直到我意識到,這僅與devtools工作,而不是如果包被正確加載,因爲鎖定的環境

3.將新env附加到搜索路徑

.onLoad <- function(libname, pkgname) { 
    assign("aliases", new.env(), envir = parent.env(environment())) 
    attach(aliases) 
    invisible() 
} 

addAlias <- function(x) assign(x, foo, aliases) 

這個我不喜歡,因爲使用了attach。在這種情況下是否有必要?我什麼時候會detach

4.公開一個單獨的命名環境

#' @export 
#' @keywords internal 
aliases <- new.env() 

addAlias <- function(x) assign(x, foo, aliases) 

這工作,但不是能調用bar(),用戶需要撥打alises$bar()mypackage::aliases$bar()。我不喜歡那樣,但這是一個有趣的實驗。我也不知道是否可以導出這樣的變量?

任何幫助表示讚賞

回答

1

我覺得更合適的方法是使用closure

#' @export 
foo <- function() "Hello" 
#' @export 
getfoo <- function() { 
    function(){ 
     # do anything, including running foo() 
     foo() 
    } 
} 

有了這個,你可以做

> bar <- getfoo() 
> bar() 
[1] "Hello" 
+0

謝謝你的提示。但我不認爲這回答了主要問題? –

+0

我認爲這是實現你想要做的事情的另一種解決方案。我認爲將變量分配給鎖定環境並不是達到此目的的有效方法。 –

+0

所以爲了確保我理解 - 使用這種方法,您建議用戶將變量賦值給變量,而不是在代碼中執行,對嗎?我想讓用戶傳入一個字符串矢量並將它們分配給我的函數。我沒有看到這個代碼怎麼做? –

相關問題