2011-03-28 9 views
19

Quería aclarar algunas cosas de este original post. La respuesta sugirió que Ruby busca para la definición constante en este orden:Ruby Koans: ámbito explícito en una definición de clase parte 2

  1. El alcance de encerramiento
  2. Cualquier ámbitos exteriores (repetir hasta que el nivel superior se alcanza)
  3. módulos incluidos
  4. Superclass (es)
  5. objeto
  6. Kernel

Así que para aclarar, por lo ¿Qué paso (1-6) es el valor de la constante LEGS que se encuentra para legs_in_oyster? ¿Es de la Superclase Animal? ¿Se ignora el alcance de la clase MyAnimals porque no se considera un ámbito adjunto? ¿Esto se debe a la definición de clase explícita MyAnimals::Oyster?

Gracias! Solo trato de entender. Aquí está el código:

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

Alguien le preguntó sobre este koan antes: http://stackoverflow.com/questions/4627735/ruby-explicit-scoping-on-a-class-definition –

+0

@Andrew - Especifiqué eso en la publicación. Solo intento generar más discusión sobre el tema porque hay partes que no entendí. ¿Debería solo comentar allí? –

+0

Lo siento, no me di cuenta. –

Respuesta

31

Estaba reflexionando sobre la misma pregunta del mismísimo koan. No soy un experto en el ámbito, pero la siguiente explicación simple tiene mucho sentido para mí, y tal vez te ayude también.

Al definir MyAnimals::Oyster que aún se encuentran en el ámbito global, por lo que el rubí no tiene conocimiento del valor LEGS ajustado a 2 en MyAnimals porque en realidad nunca está en el alcance de MyAnimals (un poco contrario a la intuición).

Sin embargo, las cosas serían diferentes si tuviera que definir Oyster esta manera:

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

La diferencia es que en el código anterior, en el momento de definir Oyster, se le ha caído en el ámbito de MyAnimals , por lo que ruby ​​sabe que LEGS se refiere a MyAnimals::LEGS (2) y no a Animal::LEGS (4).

FYI, tengo esta idea de la siguiente URL (se hace referencia en la pregunta se enlazó a):

+0

Gracias @bowsersenior! Vi ese enlace pero no lo leí lo suficiente. Error de usuario. –

+0

Creo que debería ser 'Oyster

+0

Gracias @AndreyBotalov! Actualizado el código para corregirlo. – bowsersenior

Cuestiones relacionadas