2014-10-20 3 views
0

Следующая определяет метод, который имеет upcased имя, и пытается вызвать его, но терпит неудачу:Upcased метод не обнаружен

class Module 
    def Foo; puts "foo" end 
end 

class A 
    Foo 
end 
# => uninitialized constant A::Foo 

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

Если я неоднозначность его как метод, метод обнаружения:

class A 
    Foo() 
end 
# => foo 

Когда имя метода не upcased, посмотреть не удастся.

class Module 
    def foo; puts "foo" end 
end 

class A 
    foo 
end 
# => foo 

Почему метод поиска не работает с двусмысленными усовершенствованными методами?

ответ

3

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

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

  • для переменных экземпляра, переменные класса и глобальные переменные, нет никакой двусмысленности
  • для локальных переменных, такая конструкция всегда интерпретируется как отправить сообщение, если локальная переменная не находится в Объем, то он интерпретируется как переменное разыменование
  • констант, оно всегда интерпретируются как переменное разыменование

поскольку эта неопределенность возникает только при наличии receiverless argumentless отправка сообщения, он может быть легко решена путем добавление eit ее приемник или список аргументов.

+0

Что делает случай констант отличным от локальных переменных? – sawa

+1

Различие между сообщениями и переменными различиями производится статически. Выяснение, какие локальные переменные находятся в области видимости, может быть сделано статически, но для констант это будет эквивалентно решению проблемы остановки. Или хуже: 'модуль Foo; Bar =: baz end; если rand> 0,5, тогда включайте конец Foo; Бар № бар в области или нет? ' –

+0

Я вижу. Я чувствую, что получил (но все еще понимаю). – sawa

Смежные вопросы