2010-10-01 11 views
3

Ne sont-ils pas censés faire la même chose? Pourquoi cela arrive-t-il? À ce stade, j'utilise le module_eval dans mon code par nécessité, mais le const_set semble plus lisible. Peu importe, j'aimerais vraiment comprendre pourquoi cela arrive.Différence entre le module # const_set et le module # module_eval

est ici le code:

class A 
    def foo 
    FOO 
    end 
    def self.foo 
    FOO 
    end 
end 
module B 
    class C < A 

    end 
end 
B.const_set(:FOO,'asdf') 
>> B::C.foo 
NameError: uninitialized constant A::FOO 
    from ./foo.rb:6:in `foo' 
    from (irb):1 
>> B.module_eval {FOO='asdf'} 
=> "asdf" 
>> B::C.foo 
=> "asdf" 
+3

Ne pas oublier de reconnaître que quelqu'un a répondu à votre question; sélectionnez la réponse – Tom

Répondre

2

Votre module_eval ne met pas réellement la constante dans le module. Ensuite, vous êtes juste d'y accéder de la principale:

module B;end 
B.module_eval { FOO = 'asdf' } 
>> FOO 
=> "asdf" 

Vous pouvez corriger cela avec self::FOO = 'asdf', alors il est le même que B.const_set(:FOO,'asdf'). Vous pouvez aussi le faire plus directement comme ceci:

B::FOO = 'asdf' 

Le principal problème avec votre code est que vous ne pouvez pas accéder à des constantes d'autres modules comme ça. Si elles sont dans un module externe, vous devez préciser la portée de la constante avec le préfixe :::

def foo 
    B::FOO 
end 
+0

Ah, merci. Ceci explique cela. Retour à la planche à dessin :( – Mike