Просто добавим немного более подробного объяснения: в Ruby существует неоднозначность между ссылками на переменные и отправкой сообщений.
foo
Foo
Может или означать «разыменовать переменную с именем foo
(или Foo
)» или », отправив сообщение :foo
(или :Foo
) с пустым список аргументов для получателя по умолчанию ".
Эта неопределенность разрешается следующим образом:
- Если
foo
начинается со строчной буквы, предполагается, что это отправка сообщения, если только синтаксический анализатор не видел присвоение foo
ранее, и в этом случае он обрабатывается как переменная разыменования. (Обратите внимание, что задание должно только проанализировано , не выполнено; if false then foo = nil end
совершенно нормально.)
- Если
Foo
начинается с заглавной буквы, она обрабатывается как переменная (или скорее постоянная) разыменование, если только вы не передаете список аргументов (даже пустой), в этом случае он обрабатывается как отправка сообщения.
В этом случае RuntimeError
обрабатывается как отправка сообщения, поскольку у него есть список аргументов: "must have a thing!"
. Это, конечно, из-за другой особенности Ruby, а именно, что она позволяет вам оставлять скобки вокруг списка аргументов, пока он однозначен.
IOW: все это интерпретируется примерно как
self.RuntimeError("must have a thing!")