2011-03-28 2 views
19

Je voulais clarifier certaines choses de cet original post. La réponse a suggéré que Ruby cherche la définition constante dans cet ordre:Ruby Koans: délimitation explicite sur une partie définition de classe 2

  1. La portée englobante
  2. Tous les champs externes (répéter jusqu'à ce que le niveau supérieur est atteint)
  3. modules inclus
  4. superclasse (es)
  5. objet
  6. noyau

donc, pour clarifier, à quelle étape (1-6) est la valeur de la constante LEGS trouvée pour legs_in_oyster? Est-il de la Superclasse Animal? La portée de la classe MyAnimals est-elle ignorée car elle n'est pas considérée comme une portée englobante? Est-ce dû à la définition explicite de la classe MyAnimals::Oyster?

Merci! J'essaie juste de comprendre. Voici le code:

class Animal 
    LEGS = 4 
    def legs_in_animal 
    LEGS 
    end 

    class NestedAnimal 
    def legs_in_nested_animal 
     LEGS 
    end 
    end 
end 

def test_nested_classes_inherit_constants_from_enclosing_classes 
    assert_equal 4, Animal::NestedAnimal.new.legs_in_nested_animal 
end 

# ------------------------------------------------------------------ 

class MyAnimals 
    LEGS = 2 

    class Bird < Animal 
    def legs_in_bird 
     LEGS 
    end 
    end 
end 

def test_who_wins_with_both_nested_and_inherited_constants 
    assert_equal 2, MyAnimals::Bird.new.legs_in_bird 
end 

# QUESTION: Which has precedence: The constant in the lexical scope, 
# or the constant from the inheritance heirarachy? 

# ------------------------------------------------------------------ 

class MyAnimals::Oyster < Animal 
    def legs_in_oyster 
    LEGS 
    end 
end 

def test_who_wins_with_explicit_scoping_on_class_definition 
    assert_equal 4, MyAnimals::Oyster.new.legs_in_oyster 
end 

# QUESTION: Now Which has precedence: The constant in the lexical 
# scope, or the constant from the inheritance heirarachy? Why is it 
# different than the previous answer? 
end 
+0

Quelqu'un a demandé sur ce koan avant: http://stackoverflow.com/questions/4627735/ruby-explicit-scoping-on-a-class-definition –

+0

@Andrew - J'ai spécifié cela dans le post. J'essaie juste de construire plus de discussion sur le sujet parce qu'il y a des parties que je n'ai pas comprises. Devrais-je commenter là? –

+0

Désolé, je n'ai pas remarqué ça. –

Répondre

31

Je réfléchissais justement à la même question du même koan. Je ne suis pas un expert en la matière, mais l'explication simple suivante a eu beaucoup de sens pour moi, et peut-être que cela vous aidera aussi.

Lorsque vous définissez MyAnimals::Oyster vous êtes toujours dans la portée globale, si Ruby n'a pas connaissance de la valeur LEGS réglée sur 2 dans MyAnimals parce que vous n'êtes jamais réellement dans le cadre de MyAnimals (un peu contre-intuitif).

Cependant, les choses seraient différentes si vous deviez définir Oyster cette façon:

class MyAnimals 
    class Oyster < Animal 
    def legs_in_oyster 
     LEGS # => 2 
    end 
    end 
end 

La différence est que dans le code ci-dessus, au moment où vous définissez Oyster, vous avez laissé tomber dans le champ d'MyAnimals , donc ruby ​​sait que LEGS se réfère à MyAnimals::LEGS (2) et non Animal::LEGS (4).

Pour votre information, je suis arrivé cette idée de l'URL suivante (référencé dans la question que vous avez lié à):

+0

Merci @bowsersenior! J'ai vu ce lien mais je n'ai pas lu assez loin. Erreur de l'utilisateur –

+0

Je pense que ce devrait être 'Oyster

+0

Merci @AndreyBotalov! Mise à jour le code pour le corriger. – bowsersenior

Questions connexes