12

現在純粋な Ruby である gem を開発していますが、機能の 1 つでより高速な C バリアントも開発しています。この機能は純粋な Ruby で使用できますが、速度が遅い場合があります。速度の遅さは一部の潜在的なユーザーにのみ影響を与えます (ユーザーが必要とする機能とその使用方法によって異なります)。そのため、ターゲット システムでコンパイルできない場合に、Ruby 専用関数への適切なフォールバックで gem を利用できるようにすることは理にかなっています。

この機能の Ruby および C バリアントを 1 つの gem で維持し、インストール時に gem から最高の (つまり最速の) エクスペリエンスを提供したいと考えています。そうすれば、私の 1 つのプロジェクトから、潜在的なユーザーの幅広いセットをサポートすることができます。また、互換性のための最小公分母バージョンとは対照的に、他の人々の依存する宝石やプロジェクトがターゲットシステムで利用可能な最良の依存関係を使用できるようになります。

require実行時のフォールバックが次のlib/foo.rbようにメイン ファイルに表示されることを期待します。

begin
  require 'foo/foo_extended'
rescue LoadError
  require 'foo/ext_bits_as_pure_ruby'
end

ただし、「foo_extended」をビルドできるかどうかに関係なく、gem が正しくインストールされるように、gem のインストールでネイティブ拡張機能のサポートを確認する (または試行して失敗する) 方法がわかりません。これを行う方法を調査したとき、主に数年前からの議論を見つけまし Ruby gems が実際にはこの機能をサポートしていないことを示唆する pipermail/rubygems-developers/2007-November/003220.html 。最近は何もないので、SOの誰かが最新の知識を持っていることを願っていますか?

私の理想的な解決策は、拡張機能のビルドを試行する前に、対象の Ruby が C ネイティブ拡張機能をサポートしていない (または単にプロジェクト レベルでサポートしていない) ことを検出する方法です。しかし、あまり汚れていなければ、try/catch メカニズムも問題ありません。

これは可能ですか?それとも、検索時に見つけた2 つの gem バリアント (例:fooと) を公開するというアドバイスは、まだ現在のベスト プラクティスですか?foo_ruby

4

3 に答える 3