Gemモジュールを介して、現在Gemがインストールされているかどうかを確認する方法はありますか? Rubyコードから、「gemリスト」を実行するのではなく......
明確にするために-ライブラリをロードしたくありません。それが利用可能かどうかを確認したいだけなので、すべてのrescue LoadError
ソリューションは私を助けません。また、gem自体が動作するかどうかは気にしません。それがインストールされているかどうかだけです。
私見の最善の方法は、Rayがすでに示したように、GEMをロード/要求して、例外を救うことです。 LoadError例外はGEM自体によって発生するのではなく、requireコマンドの標準的な動作であるため、レスキューしても安全です。
代わりにgemコマンドを使用することもできます。
begin
gem "somegem"
# with requirements
gem "somegem", ">=2.0"
rescue Gem::LoadError
# not installed
end
Gemコマンドの動作はrequireコマンドと同じですが、若干の違いがあります。私の知る限り、それはまだメインのGEMファイルを自動ロードしようとします。
Rubygems.rbファイルを掘り下げる(310行目)次の実行が見つかりました
matches = Gem.source_index.find_name(gem.name, gem.version_requirements)
report_activate_error(gem) if matches.empty?
実際にライブラリをロードせずにダーティーチェックを行う方法についてのヒントを提供します。
またあります:
Gem.available?('somegem')
正規表現も使用できます。 「rcov」や「relevance-rcov」などのGitHubバリアントを許可する場合に便利です。
Gem.available?(/-?rcov$/)
Gem APIのドキュメントを見ると、 Gem :: Specification :: find_all_by_name を使用してgemの可用性をテストするのは妥当なようです。
if Gem::Specification::find_all_by_name('gemname').any?
do stuff
end
find_all_by_name
は、一致するものが見つからない場合に例外を発生させるfind_by_name
とは対照的に、常に(仕様オブジェクトの)配列を返します。
Gem.availableから?は非推奨です(argh!)。もう一度救助する必要があります(double aaargh)。はい、gemが見つからない場合、find_by_nameは例外をスローします。したがって、古いrubygemとの下位互換性を保つために、一般的な解決策は次のようになります。
def gem_available?(name)
Gem::Specification.find_by_name(name)
rescue Gem::LoadError
false
rescue
Gem.available?(name)
end
新しいメソッドを使用すると、特定のバージョンを渡して、それがロードされているかどうかを確認できます。
Gem::Specification.find_by_name('Rails', '3.0.4')
あなたは出来る:
begin
require "somegem"
rescue LoadError
# not installed
end
ただし、これはモジュールがgemまたはその他の方法でインストールされたかどうかを通知しません。
私はこのコードを使用し、それはスムーズに動作します。
def gem_available?(gem_name, version = nil)
version.nil? gem(gem_name) : gem(gem_name, version)
rescue Gem::LoadError
false
end
ラック1.9.1がインストールされていると仮定します。
puts gem_available?('rack') # => true
puts gem_available?('rack', '>=2') => # false
これはどこにも表示されませんでしたが、あいまいなバージョンの文字列をfind_by_name
とfind_all_by_name
に渡すこともできます。
Gem::Specification.find_all_by_name('gemname', '>= 4.0').any?