1. ホーム
  2. r

[解決済み] Imports/Dependsを使用する際の説明の改善

2022-04-30 02:32:50

質問

の"です。 R拡張の書き方 "マニュアルでは、Imports や Depends をいつ使用するかについて、以下のガイダンスを提供しています。

一般的なルールは

  • library(pkgname) を使ってパッケージを読み込むために必要な名前空間のみを持つパッケージは、 'Imports' フィールドにリストアップしなければならず、'Package' フィールドにはリストアップしてはいけません。 Depends' フィールド。
  • library(pkgname) を使ってパッケージを正常にロードするためにアタッチする必要があるパッケージは、 'Depends' 欄にのみリストアップする必要があります。

どなたか、もう少し分かりやすく説明していただけませんか? 自分のパッケージが名前空間のみをロードする必要があるときと、パッケージがアタッチされる必要があるときと、どう区別すればいいのでしょうか? 両方の例は何ですか? 典型的なパッケージは、時々他のパッケージの関数を呼び出す関数のコレクションだと思います(すでにいくつかの作業がコード化されている)。 これは、上記のシナリオ1または2でしょうか?

編集

を書きました。 ブログ記事 この特定のトピックに関するセクションを持つ('Imports v Depends'で検索)。 ビジュアルがあると、より理解しやすくなりますね。

解決するには?

"Imports" よりも安全です。 "Depends" (を使用する他のパッケージに対して、「より良い市民」になります)。 "Depends" ).

A "Depends" ディレクティブは他のパッケージの関数が利用可能であることを保証するために、 他のパッケージをメインの検索パス (すなわち search() ). しかし、後から読み込まれた別のパッケージが、同じ名前の関数を検索パスの早い位置に配置した場合、この戦略は妨げられる可能性があります。 チェンバース ( SoDAにおける ) は、関数の例として "gam" の両方にあります。 gammgcv パッケージを使用します。他の2つのパッケージがロードされた場合、そのうちの1つは gam に依存し、1つは mgcv を呼び出すことで見つかる関数です。 gam() は、これら2つのパッケージが添付された順番に依存することになります。これはよくない。

"Imports" ディレクティブを使用する必要があります。 <imports:packageName> (の直後で検索されます。 <namespace:packageName> ) を、通常の検索パスではなく もし上の例のパッケージのどちらかが "Imports" メカニズム(これはまた import または importFrom ディレクティブを NAMESPACE ファイル)の場合、2つの方法で問題が改善されるでしょう。(1) パッケージ自身が、どの mgcv 関数が使用されます。(2) インポートされたオブジェクトからメインの検索パスをクリアにしておくことで、他のパッケージの依存関係を壊す可能性もなく、他の mgcv 関数を使用します。

これが、名前空間を使うことが良い習慣であり、CRAN で強制されている理由であり、(特に) "Imports" を使用するよりも安全です。 "Depends" .


重要な注意事項を追加するために編集しました。

があります。 残念ながら、上記のアドバイスにはよくある例外があります。 A それ自体が "Depends" 別のパッケージで B を使用する場合、あなたのパッケージはおそらく A を付けて "Depends ディレクティブを使用します。

これは、以下の理由からです。 パッケージ内の関数 A を想定して書かれたもので、パッケージ B とその関数が search() パス .

A "Depends" ディレクティブは、パッケージのロードとアタッチを行います。 A このとき、パッケージ A 自身の "Depends" ディレクティブは、連鎖反応的に、パッケージの B がロードされ、同様にアタッチされます。パッケージ内の関数 A は、その後にパッケージ B に依存している。

An "Imports" ディレクティブはロードされますが ではなく パッケージのアタッチ A となります。 どちらも ロード また アタッチパッケージ B . ( "Imports" 結局のところ、パッケージの作者は名前空間の仕組みを使うことを想定しており、パッケージの A を使用することになります。 "Imports" にあるすべての関数を指し示すために B にアクセスする必要があります)。パッケージ内の関数への関数コール A パッケージの関数に依存している B は結果的に失敗します。

のどちらかしか解決策はない。

  1. パッケージをアタッチする A を使用しています。 "Depends" ディレクティブを使用します。
  2. 長い目で見れば、パッケージのメンテナに連絡するのがよいでしょう。 A のMartin Morganの言葉を借りれば、名前空間をもっと注意深く構築するようにお願いすることです。 この関連回答 ).