短縮版
私の「ケース」を読みたくない人にとって、これが本質です。
- 新しいパッケージが既存のコードを壊す可能性を最小限に抑える、つまり、作成するコードを可能な限り堅牢にするための推奨される方法は何ですか?
名前空間メカニズムを最大限に活用するための推奨される方法は何ですか
a)提供されたパッケージを使用しているだけですか(たとえば、一部のR分析プロジェクトで)?
b)独自のパッケージの開発に関して?
クラス(AFAIU)に匹敵する名前空間メカニズムすら存在しないため、正式なクラス(私の場合は主に参照クラス)に関する競合を回避するにはどうすればよいですか?
::
Rユニバースの仕組み
これは、約2年前から頭の中で悩んでいることですが、満足のいく解決策に到達したとは思えません。それに、悪化しているように感じます。
CRAN、github、R-Forgeなどでパッケージの数が増え続けていますが、これは非常に素晴らしいことです。
このような分散型環境では、Rを構成するコードベース(簡単にするために、ベースRと寄与R)が、堅牢性に関して理想的な状態から逸脱するのは当然です。人々はさまざまな規則に従います。S3、S4があります。 、S4参照クラスなど。規則を適用する「中央クリアリングインスタンス」があった場合のように、物事を「調整」することはできません。大丈夫。
問題
上記のことを考えると、Rを使用して堅牢なコードを作成するのは非常に難しい場合があります。必要なものがすべてベースRにあるわけではありません。特定のプロジェクトでは、かなりの数の寄稿パッケージをロードすることになります。
IMHO、その点での最大の問題は、名前空間の概念をRで使用する方法です。Rでは、名前空間を明示的に要求することなく、特定の関数/メソッドの名前を簡単に記述できます(つまりfoo
、namespace::foo
)。
簡単にするために、それは誰もがしていることです。しかし、そうすれば、名前の衝突、壊れたコード、コードを書き直したりリファクタリングしたりする必要性は時間の問題です(またはロードされたさまざまなパッケージの数の問題です)。
せいぜい、新しく追加されたパッケージによってどの既存の関数がマスク/オーバーロードされているかを知ることができます。最悪の場合、コードが壊れるまで手がかりはありません。
いくつかの例:
- RMySQLとRSQLiteを同時にロードしてみてください。うまくいきません。
- また、 RMongoはRMySQLの特定の機能を上書きします
- 予測は、ARIMA関連の機能に関して多くのものを覆い隠します
- R.utils
base::parse
はルーチンをマスクします
(特にどの機能が問題を引き起こしていたのか思い出せませんが、興味があればもう一度調べてみてください)
驚いたことに、これは多くのプログラマーを悩ませているようには見えません。私はr-develで数回関心を高めようとしましたが、あまり役に立ちませんでした。
::
演算子を使用することの欠点
- Dominick Samperiが指摘したように、演算子を使用する
::
と、特定のコンテキストで効率が大幅に低下する可能性があります。 - 独自のパッケージを開発する場合
::
、コードはまだ実際のパッケージではなく、名前空間もまだないため、独自のコード全体で演算子を使用することもできません。したがって、最初はfoo
方法に固執し、ビルドし、テストしてから、すべてをに変更することに戻る必要がありnamespace::foo
ます。あまり。
これらの問題を回避するための可能な解決策
- 各パッケージの各関数を、特定の命名規則に従う変数に再割り当て
namespace..foo
します。たとえば、関連する非効率性を回避するためです(ここnamespace::foo
で一度概説しました)。長所:それは動作します。短所:不器用で、使用するメモリが2倍になります。 - パッケージを開発するときに名前空間をシミュレートします。AFAIU、これは実際には不可能です、少なくとも当時私はそう言われました。
- の使用を必須にします
namespace::foo
。私見、それが最善の方法です。確かに、ある程度の単純さは失われますが、Rユニバースはもはや単純ではありません(少なくとも00年代初頭ほど単純ではありません)。
そして、(正式な)クラスはどうですか?
上記の側面とは別に、::
wayは関数/メソッドに対して非常にうまく機能します。しかし、クラス定義はどうですか?
そのクラスでパッケージtimeDatetimeDate
を取ります。クラスもある別のパッケージが付属しているとしましょうtimeDate
。timeDate
2つのパッケージのいずれかからクラスの新しいインスタンスが必要であることを明示的に示す方法がわかりません。
このようなものは機能しません:
new(timeDate::timeDate)
new("timeDate::timeDate")
new("timeDate", ns="timeDate")
ますます多くの人々がRパッケージをOOPスタイルに切り替え、多くのクラス定義につながるため、これは大きな問題になる可能性があります。クラス定義の名前空間を明示的にアドレス指定する方法があれば、ポインタをいただければ幸いです。
結論
これは少し長かったですが、核となる問題/質問を指摘でき、ここでもっと意識を高めることができればと思います。
devtoolsとmvbutilsには、広める価値のあるアプローチがいくつかあると思いますが、もっと言うことがあると確信しています。