Какова реальная причина для заглаживания имен классов Ruby?

StackOverflow https://stackoverflow.com/questions/1993996

  •  22-09-2019
  •  | 
  •  

Вопрос

Итак, все знают, что капитализированные идентификаторы считаются «постоянными» в Ruby.

Тем не менее, можно присвоить новое значение константам, поэтому следующие работы

class A
  def self.hi; "hi"; end
end
class B
  def self.hi; "ho"; end
end
A.hi # => "hi"
B.hi # => "ho"
A = B
#  warning: already initialized constant A
# => B
A.hi # => "ho"

а также присваивает работу по узлу идентификатора:

a = B
a.hi # => "ho"

Тем не менее, внутреннее имя установлено на «B» во всех случаях, а новые имена идентификаторов также ссылаются только на «B».

Но если для идентификатора технически нормально иметь нижнее имя, почему это ограничение на внутреннее имя для класса? Не может быть то, что это должно быть постоянным, потому что это не постоянное; Таким образом, другая причина может быть в том, что идентификаторы строк имеют другую область. Но потом: почему не провести урок с прицелом с нижним регистом?

Мне интересно, потому что анализатор даже допускает имена методов в Unicode и тому подобное, поэтому кажется странным, что для классов это намного более ограничено.

Это было полезно?

Решение

Как вы сказали, имя класса - это первая константа, на которую он был назначен. Вы можете использовать только константы с class ключевое слово, потому что было решено, что class Ключевое слово следует использовать только для создания названных классов.

Обоснование, вероятно, заключается в том, что разрешение местных переменных путает использование, кто будет использовать class lowercase_class_name, не зная разницы между идентификаторами нижнего регистра и верхнего регистра, а затем задается вопросом, почему классное имя не было видно повсюду (т.е. почему def foo() lowercase_class_name.new end не сработало).

Сделав способ по умолчанию для создания классов, специфичных для констант, классы, определенные таким образом, будут видны повсюду, и есть, по крайней мере, предположение, что значение, связанное с этим именем, не должно меняться (то есть вы получаете предупреждение иначе).

Люди, которые знают, что они делают, все еще могут сделать local_variable = Class.new { ... } Если им нужно.

Другие советы

Интерпретатору нужен один из способов выяснить, является ли это именем класса или переменной члена текущего класса/модуля.

Интерпретатор должен искать имена классов в глобальной хеш -таблице, в то время как переменные участника находятся в хэш -таблице класса. Местные переменные различны, так как они могут быть разрешены интерпретатором, не смотря на хэш -таблицы вообще (они имеют приоритет по переменным членам).

И единственное, что интерпретатор знает об идентификаторе, это персонажи. Поэтому есть нотационная разница. Это также причина, по которой глобальные переменные имеют предыдущие переменные $ и класса символ @. Для этого у интерпретатора есть другие хэш -таблицы, которые он должен искать.

Другие языки сценариев имеют сходные ограничения, например, PHP нуждается в долларе перед каждой переменной.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top