2016-04-26 14 views
2

我知道有相關的帖子,但答案不足。所以請認真回答這個問題。在哪裏以及如何定義一個通用函數,如果使用多個包

有兩個軟件包(「keithley」和「xantrex」)控制兩個不同的硬件設備。因此,兩者都是彼此獨立的。他們每個人都必須分開初始化。所以我寫了兩個方法

init.keithley(inst,...) # in keythley package 

init.xantrex(inst,...) # in xantrex package 

爲通用S3功能init(inst,...)。我試圖在keithley包和xantrex包中聲明通用函數,但是一旦後者加載並找不到方法,它就會被屏蔽。

我想什麼是.onAttach() -hook

.onAttach <- function(libname, pkgname) 
{ 
    if(!exists("init")) 
    eval(expression(init <- function(inst,...) UseMethod("init")),envir = .GlobalEnv) 
} 

但隨着這是不可能評估包命名空間中的init()功能。這可以通過選項envir = environment()來證明,這將不起作用。我也試過setGenericS3()setGeneric(),結果總是一樣的。 「髒」的解決方案可能是定義第三個包並導入它,但必須有一個乾淨的方法來做到這一點。

何處以及如何定義泛型函數?

+0

以下是否有效? 'keithley :: init(...)'和'xantrex :: init(...)' – lmo

+0

這應該可以工作,但並不打算。我們應該使用這些包,比如'init(keith)'和'init(xan)'等等,而不顯式調用這個名稱空間。 – Seily

+0

做'環境(init)< - asNamespace('xantrex')'工作嗎?用在你的onAttach – rawr

回答

0

下面是解:

據我所知,附接的封裝具有三種環境的這些不同的含義在這裏詳細地解釋(例如"package:Xantrex""namespace:Xantrex""imports:Xantrex"):Advanced R

現在,我們必須測試通用函數init()是否已經存在,如果沒有,我們必須在正確的環境中初始化它。以下代碼將爲我們做到這一點。

.onAttach <- function(libname, pkgname) 
{ 
    if(!exists("init",mode = "function")) 
    eval(expression(init <- function(inst,...) UseMethod("init")),envir = as.environment("package:Xantrex")) 
} 

.onAttach -hook,要保證不同的命名空間進行初始化。相比之下,掛鉤太早了。提及表達式在package:Xantrex環境中進行了評估,因此泛型在搜索路徑中變得可見。

下一頁到照顧,你的空間文件將export(init.xantrex)S3method(init,xantrex)。後者將導致錯誤,因爲在構建包時,方法init.xantrex()的通用不存在。

最好! Martin

相關問題