Ruby作用域和常量优先级:词法作用域还是继承树。

17

我将展示rubykoans教程中的代码片段。rubykoans是一个网站。以下是代码:

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 hierarchy?
# ------------------------------------------------------------------

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 hierarchy?  Why is it
# **different than the previous answer**?

实际上问题在评论中(我用星号*突出了它(尽管本来应该是加粗的))。有人能解释一下吗?提前谢谢!

1个回答

35

这里有答案:Ruby: explicit scoping on a class definition。但也许不是非常清晰。如果您阅读链接的文章,将有助于回答。

基本上,BirdMyAnimals 的作用域中声明,当解析常量时,该作用域具有更高的优先级。OysterMyAnimals 命名空间中,但没有在该作用域中声明。

在每个类中插入 p Module.nesting 将显示封闭作用域。

class MyAnimals
  LEGS = 2

  class Bird < Animal

    p Module.nesting
    def legs_in_bird
      LEGS
    end
  end
end

结果: [AboutConstants::MyAnimals::Bird, AboutConstants::MyAnimals, AboutConstants]

并且

class MyAnimals::Oyster < Animal
  p Module.nesting

  def legs_in_oyster
    LEGS
  end
end

结果: [AboutConstants::MyAnimals::Oyster, AboutConstants]

看到区别了吗?


3
包括 Module.nesting 使得这个答案成为了你链接的优秀补充。 - Tomboyo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接