2016-04-26 27 views
2

関連記事があるが、回答が不十分であることは知っている。だからこの質問に真剣に答えてください。複数のパッケージが使用されている場合、汎用関数を定義する場所と方法

2つの異なるハードウェアデバイスを制御する2つのパッケージ( "keithley"と "xantrex")があります。従って、両者は互いに独立している。それぞれは別々に初期化する必要があります。だから私は、二つの方法の一般的なS3機能init(inst,...)ため

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

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

を書きました。 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()と同じ結果を試しました。 "汚い"ソリューションは、3番目のパッケージを定義してインポートすることができますが、これを行うにはきれいな方法が必要です。

どこでどのように汎用関数を定義する必要がありますか?ここで

+0

以下は機能しますか? 'keithley :: init(...)'と 'xantrex :: init(...)' – lmo

+0

これはうまくいくはずですが、意図したものではありません。これらのパッケージは、 'init(keith)'や 'init(xan)'などの行で明示的に名前空間を呼び出して使用する必要があります。 – Seily

+0

は 'environment(init)< - asNamespace( 'xantrex')'は動作しますか?あなたのonAttachで使用される – rawr

答えて

0

は、ソリューションです:

私は理解しているように、付属のパッケージには3つの環境(例えば"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フックは、異なる名前空間が初期化されることを保証するために必要です。これとは対照的に、.onLoad -hookは早すぎるでしょう。式がpackage:Xantrex環境で評価されるため、ジェネリックが検索パスに表示されるようになります。

次にNAMESPACEファイルはexport(init.xantrex)ではなくS3method(init,xantrex)となるよう注意してください。後者の場合は、パッケージを作成するときにメソッドinit.xantrex()の汎用が存在しないため、エラーが発生します。

ベスト! Martin