質問

Gem モジュールを介して、何らかの gem が現在インストールされているかどうかを確認する方法はありますか?「gem list」を実行するのではなく、Ruby コードから...

明確にするために、ライブラリをロードしたくないのです。利用可能かどうかを確認したいだけなので、 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を使用して、Gem APIドキュメントをご覧ください。 :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!)であるため、再度レスキューする必要があります(ダブルaaargh)。はい、gemが見つからない場合、find_by_nameは例外をスローします。したがって、古いrubygemsとの後方互換性を保つために、一般的な解決策は次のように思われます:

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
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top