为什么在数组中声明常量并将其分配给其他常量,这些常量在Ruby中可作为类常量访问? [英] Why are constants declared inside an array, and assigned to other constants, accessible as Class constants in Ruby?

查看:70
本文介绍了为什么在数组中声明常量并将其分配给其他常量,这些常量在Ruby中可作为类常量访问?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出以下Ruby类

class Example
  PARENTS = [
    FATHER = :father,
    MOTHER = :mother
  ]
end

预期

> Example::PARENTS
#=> [:father, :mother]
> Example::PARENTS[0]
#=> :father
> Example::PARENTS[1]
#=> :mother

但是,为什么这样做呢?

However, why does this work?

> Example::FATHER
#=> :father
> Example::MOTHER
#=> :mother

实际上,为什么在Example类的作用域中存在三个常量?

In fact, why are there three constants in the Example class's scope?

> Example.constants
#=> [:MOTHER, :PARENTS, :FATHER]

要点是,如果我用另一种方法:

To the point, that if I extend the class with an additional method:

class Example
  def self.whos_your_daddy
    FATHER
  end
end

它像平常一样访问常量。

It accesses the constant like normally.

> Example.whos_your_daddy
#=> :father

这种行为怎么可能?通过声明数组的常量 inside ,我希望它们在数组内部范围内。请在您的答案中引用相关文档。

How is this behavior possible? 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.

编辑:我想我会澄清一下,回答这个问题的最简单方法是解释两件事:

I suppose I'll clarify, the easiest way to answer this question is to explain two things:

首先,执行以下代码会发生什么:

First, what happens when the following code is executed:

PARENTS = [
  FATHER = :father,
  MOTHER = :mother
]

第二,是否在任何将常量与其声明所在类的范围相关联的地方声明了常量?为什么?

Second, does declare a constant anywhere tie it to the scope of the class it is being declared in? Why?

推荐答案


首先,执行以下代码会发生什么:

First, what happens when the following code is executed:

PARENTS = [
  FATHER = :father,
  MOTHER = :mother
]





  • PARENTS = ... 尝试设置常量 PARENTS 。但是要这样做,它必须评估赋值的右侧:


    • [...] 尝试创建一个数组。但是要这样做,它必须评估其参数:


      • FATHER =:father 集常量父亲:父亲。赋值的结果是:father ,它成为第一个参数。

      • MOTHER =:mother 将常量 MOTHER 设置为:mother 。赋值的结果是:mother ,它成为第二个参数。

        • PARENTS = ... attempts to set the constant PARENTS. But in order to do so, it has to evaluate the right-hand side of the assignment:
          • [...] attempts to create an array. But in order to do so, it has to evaluate its arguments:
            • FATHER = :father sets the constant FATHER to :father. The result of this assignment is :father which becomes the first argument.
            • MOTHER = :mother sets the constant MOTHER to :mother. The result of this assignment is :mother which becomes the second argument.
            • 所以按时间顺序的顺序:


              1. 常量父亲设置为:father

              2. 常量 MOTHER 设置为:mother

              3. 一个数组用元素:father :mother 创建的

              4. 常量 PARENTS 设置为该数组

              1. The constant FATHER is set to :father
              2. The constant MOTHER is set to :mother
              3. An array with elements :father and :mother is created
              4. The constant PARENTS is set to that array

              您的代码等效于:

              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 确定当前的嵌套,即在以下位置定义常量:(文档

              You can use Module.nesting to determine the current nesting, i.e. where a constant will be defined in: (more examples in the docs)

              class Example
                p outer_nesting: Module.nesting
                PARENTS = [
                  p(inner_nesting: Module.nesting)
                ]
              end
              

              输出:

              {:outer_nesting=>[Example]}
              {:inner_nesting=>[Example]}
              

              如您所见,数组文字不影响当前嵌套。这两个位置的常量将在示例下定义。

              As you can see, an array literal doesn't affect the current nesting. Constants in both locations will be defined under Example.

              如果您真的想在常量内部声明常量,数组(即在数组的单例类内部),您可以这样做:

              If you really wanted to declare the constants "inside" the array (i.e. inside the array's singleton class), you could do some like this:

              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]
              

              以上内容仅作演示之用,无须实际操作

              The above is just for demonstration purposes, there's no need to actually do that.

              这篇关于为什么在数组中声明常量并将其分配给其他常量,这些常量在Ruby中可作为类常量访问?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆