Я могу понять, как это может сбивать с толку, но кроме того факта, что переназначение значений константам не рекомендуется, с точки зрения области видимости - переменные экземпляра и константы чрезвычайно похожи.
Визуальный прием в первомОбъявление класса - это то, где вы объявляете константу внутри массива.
Первое: поймите, что когда вы объявляете константу, возвращаемое значение является вашим определением.Например,
FATHER = :father
#=> :father
Теперь давайте посмотрим на объявление константы:
PARENTS = [
FATHER = :father,
MOTHER = :mother
]
Для объявления PARENT
вы могли бы просто использовать:
PARENTS = [
:father,
:mother
]
, ноВы пошли дальше и объявили константу внутри определения.Теперь, пожалуйста, поймите, что область действия переменных и констант экземпляра аналогична , она привязана к экземпляру, в котором она была объявлена, и поэтому объявление константы в любом месте связало бы ее с экземпляром.
Выполнив FATHER = :father
, вы объявили другую константу, и областью действия константы всегда будет класс, в котором она была объявлена, в данном случае Example
.То же самое верно и для MOTHER = :mother
.
Если вы более привыкли к переменным экземпляра - это та же самая причина, по которой это работает: учитывая следующий класс Ruby.
class Example
@parents = [
@father = :father,
@mother = :mother
]
end
Эти работыкак и ожидалось
> Example.instance_variable_get :@parents
#=> [:father, :mother]
> Example.instance_variable_get(:@parents)[0]
#=> :father
> Example.instance_variable_get(:@parents)[1]
#=> :mother
Но это тоже работает.
> Example.instance_variable_get :@father
#=> :father
> Example.instance_variable_get :@mother
#=> :mother
Фактически, эти три находятся в области действия класса Example.
> Example.instance_variables
#=> [:@mother, :@parents, :@father]
Кстати,что если я расширю класс дополнительным методом:
class Example
def self.whos_your_daddy
@father
end
end
Он обращается к переменным экземпляра, как обычно.
> Example.whos_your_daddy
#=> :father