Как ruby ​​допускает метод и класс с одинаковым именем? - PullRequest
2 голосов
/ 07 июня 2010

Я работал над классом Singleton в ruby ​​и только что вспомнил, как он работает в factory_girl . Они сработали, так что вы можете использовать и длинный путь Factory.create(...) и короткий путь Factory(...) Я подумал об этом и мне было любопытно посмотреть, как они сделали класс Factory также ведут себя как метод.

Они просто использовали Factory дважды так:

def Factory (args)
  ...
end

class Factory
  ...
end

Мой вопрос таков: Как ruby ​​достигает этого? и есть ли опасность в использовании этого, казалось бы, причудливого паттерна?

1 Ответ

6 голосов
/ 07 июня 2010

Методы и переменные живут в разных пространствах имен. Таким образом, вы можете иметь как метод, так и переменную (или в этом случае константу) с одним и тем же именем. Однако при их использовании Ruby необходимо уметь различать. В общем, это не проблема: у сообщений есть получатели, а у переменных нет. Сообщения имеют аргументы, переменные - нет. Переменные назначены, сообщения - нет.

Единственная проблема - когда у вас нет получателя, аргумента и присваивания. Тогда Ruby не может определить разницу между отправкой сообщения без получателя без аргументов и переменной. Таким образом, он должен составить несколько произвольных правил, и эти правила в основном:

  • для неоднозначного токена, начинающегося со строчной буквы, предпочитайте интерпретировать его как отправку сообщения, , если вы точно не знаете, что это переменная (т. Е. парсер (не (! ) переводчик) видел задание раньше)
  • для неоднозначного токена, начинающегося с заглавной буквы, предпочитайте интерпретировать его как константу

Обратите внимание, что для сообщения, отправляемого с аргументами (даже если список аргументов пуст), двусмысленности нет.

  • test(): очевидно, что сообщение отправлено, здесь нет двусмысленности
  • test: может быть отправка сообщения или переменная; В правилах разрешения говорится, что это сообщение отправлено (если ранее не было присвоения test)
  • Test(): очевидно, что сообщение отправлено, здесь нет двусмысленности
  • self.Test: также очевидно, что сообщение отправлено, здесь нет двусмысленности
  • Test: может быть отправка сообщения или константа; правила разрешения говорят, что это константа
...