Je travaille sur Pickaxe 1.9, et je suis un peu troublé par la recherche constante dans les blocs instance/class_eval. J'utilise 1.9.2.Ruby: comment la recherche constante fonctionne-t-elle dans instance_eval/class_eval?
Il semble que Ruby gère-recherche constante * blocs _eval de la même manière, il ne méthode recherche:
- look pour une définition dans receiver.singleton_class (plus mixins);
- puis dans receiver.singleton_class.superclass (plus mixins);
- puis continuez l'eigenchain jusqu'à ce que vous arriviez à
#<Class:BasicObject>
; - dont la superclasse est Class;
- puis le reste de la chaîne des ancêtres (y compris
Object
, qui stocke toutes les constantes que vous définissez au plus haut niveau), la vérification de mixins le long du chemin
Est-ce exact? La discussion de Pickaxe est un peu laconique.
Quelques exemples:
class Foo
CONST = 'Foo::CONST'
class << self
CONST = 'EigenFoo::CONST'
end
end
Foo.instance_eval { CONST } # => 'EigenFoo::CONST'
Foo.class_eval { CONST } # => 'EigenFoo::CONST', not 'Foo::CONST'!
Foo.new.instance_eval { CONST } # => 'Foo::CONST'
Dans l'exemple class_eval, Foo-la-classe n'est pas un arrêt le long de la chaîne des ancêtres de Foo-the-objet!
Et un exemple avec mixins:
module M
CONST = "M::CONST"
end
module N
CONST = "N::CONST"
end
class A
include M
extend N
end
A.instance_eval { CONST } # => "N::CONST", because N is mixed into A's eigenclass
A.class_eval { CONST } # => "N::CONST", ditto
A.new.instance_eval { CONST } # => "M::CONST", because A.new.class, A, mixes in M
Remarque: À partir de Ruby 2.3, ce n'est plus vrai. – sawa