42 votes

Vérifiez la disponibilité de Ruby Gem

Est-il possible de vérifier si une gemme est actuellement installée via le module Gem? Depuis le code ruby, pas en exécutant "liste de gemmes" ...

Pour clarifier - je ne veux pas charger la bibliothèque. Je veux juste vérifier si elle est disponible, donc toutes les solutions rescue LoadError ne m'aident pas. De plus, je me moque de savoir si la gemme fonctionnera ou non, mais seulement si elle est installée.

38voto

foz Points 3258

Il y a aussi:

 Gem.available?('somegem')
 

Vous pouvez aussi utiliser des expressions regex. Pratique si je veux autoriser les variantes 'rcov' et GitHub comme 'pertinence-rcov':

 Gem.available?(/-?rcov$/)
 

37voto

Eric Drechsel Points 707

En regardant Joyau de la documentation de l'API, à l'aide de Gem::Spécification::find_all_by_name pour tester gem disponibilité semble raisonnable.

if Gem::Specification::find_all_by_name('gemname').any?
  do stuff
end

find_all_by_name renvoie toujours à un tableau (de la Spécification des objets), par opposition à l' find_by_name qui lève une exception si aucune correspondance n'est trouvée.

32voto

Simone Carletti Points 77653

À mon humble avis, le meilleur moyen est d'essayer de charger/exiger du GEM et de sauvetage de l'Exception, Ray a déjà montré. Il est sûr de sauver la LoadError exception car elle n'est pas soulevée par le BIJOU lui-même, mais c'est le comportement standard de l'exiger de commande.

Vous pouvez également utiliser la gemme de commande à la place.

begin
  gem "somegem"
  # with requirements
  gem "somegem", ">=2.0"
rescue Gem::LoadError
  # not installed
end

Le joyau de la commande a le même comportement de l'exiger de commande, avec quelques légères différences. Autant que je sache, il essaie toujours d'autoload le principal JOYAU de fichier.

Creuser dans le rubygems.rb fichier (ligne 310), j'ai trouvé la suite de l'exécution

matches = Gem.source_index.find_name(gem.name, gem.version_requirements)
report_activate_error(gem) if matches.empty?

Il peut vous fournir quelques conseils sur la façon de faire un gros chèque, sans réellement le chargement de la bibliothèque.

30voto

foz Points 3258

Depuis Gem.disponible? est déprécié (argh!), vous devez sauver à nouveau (double aaargh). Oui, find_by_name déclenche une exception si le bijou n'est pas trouvé. Donc, pour être rétro-compatible avec les anciens rubygems, la solution semble être :

def gem_available?(name)
   Gem::Specification.find_by_name(name)
rescue Gem::LoadError
   false
rescue
   Gem.available?(name)
end

Notez que la nouvelle méthode permet de transmettre une version spécifique pour voir si c'est chargé:

Gem::Specification.find_by_name('rails', '3.0.4')

6voto

Ray Vernagus Points 4276

Vous pouvez:

begin
  require "somegem"
rescue LoadError
  # not installed
end

Ce ne serait pas, cependant, de vous dire si le module a été installé par le gem ou d'autres moyens.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X