2017-01-12 2 views
2

Je possède ce code:Ruby: 'require' retourne false même si fichier non chargé

puts require './item' 
puts $" 

class Light < Item 
    #code 
end 

classe Item dans item.rb:

require './v3d' 
require './ray' 

class Item 
    attr_accessor :pos 

    def initialize(pos) 
    @pos = pos 
    end 

    def check(pos, dir) 
    return nil 
    end 

    def normal(ray) 
    return nil 
    end 
end 

que lorsque je lance mes impressions du programme de cette sortie:

false 
enumerator.so 
thread.rb 
rational.so 
complex.so 
/usr/lib/x86_64-linux-gnu/ruby/2.3.0/enc/encdb.so 
/usr/lib/x86_64-linux-gnu/ruby/2.3.0/enc/trans/transdb.so 
/usr/lib/ruby/2.3.0/unicode_normalize.rb 
/usr/lib/x86_64-linux-gnu/ruby/2.3.0/rbconfig.rb 
/usr/lib/ruby/2.3.0/rubygems/compatibility.rb 
/usr/lib/ruby/2.3.0/rubygems/defaults.rb 
/usr/lib/ruby/2.3.0/rubygems/deprecate.rb 
/usr/lib/ruby/2.3.0/rubygems/errors.rb 
/usr/lib/ruby/2.3.0/rubygems/version.rb 
/usr/lib/ruby/2.3.0/rubygems/requirement.rb 
/usr/lib/ruby/2.3.0/rubygems/platform.rb 
/usr/lib/ruby/2.3.0/rubygems/basic_specification.rb 
/usr/lib/ruby/2.3.0/rubygems/stub_specification.rb 
/usr/lib/ruby/2.3.0/rubygems/util/list.rb 
/usr/lib/x86_64-linux-gnu/ruby/2.3.0/stringio.so 
/usr/lib/ruby/2.3.0/rubygems/specification.rb 
/usr/lib/ruby/2.3.0/rubygems/exceptions.rb 
/usr/lib/ruby/vendor_ruby/rubygems/defaults/operating_system.rb 
/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_gem.rb 
/usr/lib/ruby/2.3.0/monitor.rb 
/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb 
/usr/lib/ruby/2.3.0/rubygems.rb 
/usr/lib/ruby/vendor_ruby/did_you_mean/version.rb 
/usr/lib/ruby/vendor_ruby/did_you_mean/core_ext/name_error.rb 
/usr/lib/ruby/vendor_ruby/did_you_mean/levenshtein.rb 
/usr/lib/ruby/vendor_ruby/did_you_mean/jaro_winkler.rb 
/usr/lib/ruby/vendor_ruby/did_you_mean/spell_checkable.rb 
/usr/lib/ruby/2.3.0/delegate.rb 
/usr/lib/ruby/vendor_ruby/did_you_mean/spell_checkers/name_error_checkers/class_name_checker.rb 
/usr/lib/ruby/vendor_ruby/did_you_mean/spell_checkers/name_error_checkers/variable_name_checker.rb 
/usr/lib/ruby/vendor_ruby/did_you_mean/spell_checkers/name_error_checkers.rb 
/usr/lib/ruby/vendor_ruby/did_you_mean/spell_checkers/method_name_checker.rb 
/usr/lib/ruby/vendor_ruby/did_you_mean/spell_checkers/null_checker.rb 
/usr/lib/ruby/vendor_ruby/did_you_mean/formatter.rb 
/usr/lib/ruby/vendor_ruby/did_you_mean.rb 
/home/<user>/Documents/ruby/ray/write_ppm.rb 
/home/<user>/Documents/ruby/ray/v3d.rb 
/home/<user>/Documents/ruby/ray/pixel.rb 
/home/<user>/Documents/ruby/ray/image.rb 
/home/<user>/Documents/ruby/ray/material.rb 

puis jette:

/home/<user>/Documents/ruby/ray/light.rb:4:in `<top (required)>': uninitialized constant Item (NameError) 

Lorsque require './item' est appelée, il n'y a pas d'erreur ET elle renvoie false. De ma compréhension de la façon dont fonctionne require, il semble que le programme pense à tort qu'il n'a pas besoin de charger item.rb. Pourquoi cela arrive-t-il et comment puis-je le réparer?

Edit: élargi sur un code

+0

Pouvez-vous nous montrer à quoi ressemble votre item.rb? Sentez-vous comme il pourrait y avoir quelque chose de mal avec la définition de votre classe. – Chong

+0

'item.rb' contient juste la création de la classe' Item'. Son seul but est d'avoir des classes enfants donc il n'y a presque pas de code. Ce que je trouve pertinent est que 'require './Item'' renvoie false sans erreur, mais il est clair à partir de' puts $ "' que 'item.rb' n'a jamais été chargé –

Répondre

1

J'ai résolu le problème en réécrivant totalement mes instructions require pour chaque fichier. Ce que je pense que le problème était, était la suivante:

  • item.rb contenait require './ray'
  • ray.rb contenait require './light'
  • light.rb contenait require './item' et class Light < Item

Lors du chargement item.rb, l'interprète a vu qu'il fallait aussi charge ray.rb et donc light.rb. Quand il a atteint le require './item' à l'intérieur de light.rb, il a renvoyé false car il était en train de charger ce fichier.Cependant, comme il n'était pas encore terminé, il n'apparaissait pas dans $". L'interpréteur a ensuite eu besoin d'accéder à la définition de la classe Item pour terminer le chargement light.rb, mais comme il devait terminer le chargement light.rb pour charger item.rb, l'interpréteur était un NameError.

0

Vous avez raison de dire que si require 'my_lib' renvoie false, alors 'my_lib' a déjà été chargé. Cependant, cela est différent de dire qu'une classe MyLib est définie. Est-ce que votre item.rb définit une classe Item?

Il est également possible que Item soit défini ailleurs dans la hiérarchie de l'espace de noms. par exemple. Si votre item.rb est dans some_gem/item.rb, et que vous appelez require de some_gem /, il se chargera avec succès, mais le nom de la classe pourrait être SomeGem::Item. Dans ce cas, vous ne pourrez pas y accéder directement à partir de l'espace de noms racine.

Dernière chose que je peux penser est que le fichier item.rb est en train de changer sous, ou a des morceaux très dynamiques qui perturbent l'interpréteur.

Je pense que le problème est l'un d'entre eux avant de penser que le besoin est en quelque sorte gâcher.

+0

Oui, la classe 'Item' est définie dans le fichier' item.rb' et contient très peu de code. Le résultat de l'appel 'puts $" 'montre que' item.rb' n'a pas été chargé, même si l'appel 'require '.'/Item'' (plus tôt) a renvoyé false sans erreurs –

+0

Très étrange ... C'est définitivement possible pour trouver le fichier, ou bien cela soulèverait un LoadError. 'require' et' $ ''' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' $ '' '' '' '. méta-programmation en cours. Pourriez-vous nous donner plus d'informations? Dites, le contenu de item.rb et la sortie complète de puts "$" '? Sans plus d'informations, nous ne pouvons vraiment pas faire plus que spéculer – Glyoko

+0

J'ai ajouté' item.rb' et tout le résultat de '$" ' –