Ruby Koans:对类定义第2部分的显式范围

时间:2011-03-28 20:40:08

标签: ruby

我想澄清原始post之外的一些事情。答案表明Ruby按此顺序搜索常量定义:

  1. 封闭范围
  2. 任何外部范围(重复到达最高级别)
  3. 包含的模块
  4. 超类(ES)
  5. 对象
  6. 内核
  7. 那么澄清一下,在LEGS找到的常量legs_in_oyster的值是哪一步(1-6)?它来自超类Animal吗?类MyAnimals的范围是否被忽略,因为它不被视为封闭范围?这是由于明确的MyAnimals::Oyster类定义吗?

    谢谢!只是想了解。这是代码:

     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
    

1 个答案:

答案 0 :(得分:32)

我只是在同一个公案中思考同样的问题。我不是范围界定的专家,但以下简单的解释对我来说很有意义,也许它对你也有帮助。

当您定义MyAnimals::Oyster时,您仍处于全局范围内,因此ruby不知道LEGS中的MyAnimals值设置为2,因为您实际上并不属于MyAnimals(有点违反直觉)。

但是,如果您以这种方式定义Oyster,情况会有所不同:

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

不同之处在于,在上面的代码中,当您定义Oyster时,您已进入MyAnimals的范围,因此ruby知道LEGS指的是{{1} (2)而不是MyAnimals::LEGS(4)。

仅供参考,我从以下网址获得了这一见解(在您链接的问题中引用):