给定以下 Ruby 类
class Example
PARENTS = [
FATHER = :father,
MOTHER = :mother
]
end
这些按预期工作
> Example::PARENTS
#=> [:father, :mother]
> Example::PARENTS[0]
#=> :father
> Example::PARENTS[1]
#=> :mother
但是,为什么会这样呢?
> Example::FATHER
#=> :father
> Example::MOTHER
#=> :mother
事实上,为什么在 Example 类的作用域中存在三个常量?
> Example.constants
#=> [:MOTHER, :PARENTS, :FATHER]
关键是,如果我用一个额外的方法扩展这个类:
class Example
def self.whos_your_daddy
FATHER
end
end
它像往常一样访问常量。
> Example.whos_your_daddy
#=> :father
这种行为怎么可能?通过在数组的 inside 中声明常量,我希望它们在数组的范围内。请在您的回答中引用相关文档。
编辑:我想我会澄清一下,回答这个问题最简单的方法是解释两件事:
首先,执行以下代码时会发生什么:
PARENTS = [
FATHER = :father,
MOTHER = :mother
]
其次,在任何地方声明常量是否将其与声明它的类的范围联系起来?为什么?
最佳答案
First, what happens when the following code is executed:
PARENTS = [ FATHER = :father, MOTHER = :mother ]
PARENTS = ...
尝试设置常量PARENTS
。但为了这样做,它必须评估赋值的右侧:[...]
尝试创建一个数组。但为了这样做,它必须评估其论点:FATHER = :father
将常量FATHER
设置为:father
。此赋值的结果是:father
,它成为第一个参数。MOTHER = :mother
将常量MOTHER
设置为:mother
。此赋值的结果是:mother
,它成为第二个参数。
所以按时间顺序:
- 常量
FATHER
设置为:father
- 常量
MOTHER
设置为:mother
- 创建了一个包含元素
:father
和:mother
的数组 - 常量
PARENTS
设置为该数组
你的代码等同于:
FATHER = :father
MOTHER = :mother
PARENTS = [FATHER, MOTHER] # or [:father, :mother]
By declaring the constants inside of an array, I would expect them to to be scoped inside the array. Please cite the relevant docs in your answer.
您可以使用 Module.nesting
来确定当前的嵌套,即在以下位置定义常量:(更多示例在 docs 中)
class Example
p outer_nesting: Module.nesting
PARENTS = [
p(inner_nesting: Module.nesting)
]
end
输出:
{:outer_nesting=>[Example]}
{:inner_nesting=>[Example]}
如您所见,数组文字不会影响当前的嵌套。两个位置的常量将在 Example
下定义。
如果你真的想在数组“内部”声明常量(即在数组的单例类内部),你可以这样做:
class Example
PARENTS = []
class << PARENTS
FATHER = :father
MOTHER = :mother
PARENTS.push(FATHER, MOTHER)
end
end
p Example.constants #=> [:PARENTS]
p Example::PARENTS.singleton_class.constants #=> [:FATHER, :MOTHER]
以上只是为了演示目的,没有必要实际这样做。
关于ruby - 为什么常量在数组内声明,并分配给其他常量,在 Ruby 中作为类常量访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54526667/