2017-04-20 3 views
1

Essayez de créer une gemme basée sur bundler's official guide on developing a Ruby gem.Ruby: nécessite des travaux dans la gemme, échoue lors de l'exécution à partir de la source

Courir bundle gem foodie va créer une structure et générer des fichiers dans le répertoire lib:

  • fin gourmet
    • version.rb
  • foodie.rb

fin gourmet. rb lit

require "foodie/version" 

module Foodie 
    # Your code goes here... 
end 

Exécution ruby lib/foodie.rb (ou aussi de répertoires différents) se traduira par

C:/Ruby23-x64/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- foodie/versio 
n (LoadError) 
     from C:/Ruby23-x64/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require' 
     from foodie.rb:1:in `<main>' 

D'autre part l'installation de la pierre précieuse par rake install et exigeant la pierre précieuse fonctionne très bien.

Fonctionne à partir de la source si require "foodie/version" est remplacé par require_relative "foodie/version" dans foodie.rb. Si je comprends

  • require travaux basés sur des modules
  • require_relative travaux basés sur la structure des répertoires

Pour moi, ce dernier de ressemble à un hack. Il ne serait plus judicieux de structurer votre code via des modules car il ne serait pas appliqué (peut-être que cela aurait encore du sens, mais vous pourriez faire des erreurs sans jamais le remarquer).

Mes questions sont les suivantes:

  • Est-il possible de tester un petit bijou de la source sans l'installer en suivant la convention de Bundler (en utilisant require au lieu de require_relative)?
  • Pourquoi la gemme fonctionne-t-elle après l'installation?
  • Existe-t-il une meilleure pratique pour l'utilisation de require, require_relative, les modules, les fichiers et la structure générale?

Merci.

+0

Veuillez scinder cette question en questions distinctes, parce que: 1. les trois questions que vous avez posées sont très différentes, et 2. elles seront plus utiles aux futurs lecteurs de cette façon. Merci! –

+0

Merci pour les commentaires. Je l'ai demandé de cette façon parce que ces questions ont émergé du même problème/contexte - j'imagine que d'autres ont des questions similaires dans une situation similaire. Je pense que le même contexte est requis pour chaque question. Est-ce une bonne pratique de répéter le même contexte pour plusieurs questions? – thisismydesign

Répondre

1

Vous devez ajouter votre lib dir au chemin de chargement de Ruby. Le chemin de chargement est une liste de répertoires dans lesquels Ruby recherche des fichiers lorsque vous appelez require. Rubygems gère également le chemin de chargement lorsque vous utilisez des gemmes, c'est pourquoi votre code fonctionne lorsqu'il est installé en tant que gemme.

Vous dites "si je comprends bien ... require fonctionne sur la base de modules", ce n'est pas correct. require fonctionne avec des fichiers, c'est simplement la convention qu'une classe ou un module est défini dans un fichier avec un nom correspondant, par ex. MyModule peut être dans my_module.rb.

Il existe plusieurs façons d'ajouter un répertoire au chemin de chargement.A partir de la ligne de commande, vous pouvez utiliser l'option -I:

$ ruby -I lib lib/foodie.rb 

Si vous voulez éviter de taper -I lib vous pouvez utiliser la variable d'environnement RUBYLIB. Ruby ajoute le contenu de ce sur le chemin de charge: (. Sous Windows, je pense que vous aurez besoin d'utiliser set plutôt que export)

$ export RUBYLIB=lib 
$ ruby lib/foodie.rb 

Vous pouvez également manipuler le chemin de charge de withing le programme lui-même . Il est stocké dans la variable globale $LOAD_PATH, avec un alias :$. C'est ainsi que Rubygems et Bundler gèrent vos gemmes.

+0

Merci! Deux remarques/questions: 1, Ma supposition était que même si vous définissiez plusieurs modules et classes dans un seul fichier, vous pouvez choisir de ne demander qu'une certaine classe (par exemple 'require A/B/C' avec la structure suivante dans un seul fichier : 'module A module B classe C ... extrémité fin end'). N'y a-t-il aucun moyen d'y parvenir? 2, Le point à retenir pour moi est que 'require_relative' est le même que' require', sauf que le premier a une fonctionnalité étendue et devrait donc être préféré. Êtes-vous d'accord avec cela ou y a-t-il un inconvénient à utiliser généralement 'require_relative' au lieu de' require'? – thisismydesign