2

I tried to capture undefined methods by the following definition:

def method_missing m
  puts "#{m} is missing"
end

When I write an undefined method such as foo after it, it is captured by method_missing:

foo # => foo is missing

but when I write an undefined method such as Foo, it is not captured by method_missing:

Foo # => NameError: Uninitialized constant Foo

It looks like if it is disambiguated from a constant, then it is captured:

self.Foo # => Foo is missing
Foo() # => Foo is missing

Why is Foo not captured in the first case? Is it a feature that when a method is ambiguous between a local variable, it is captured by method_missing, but not when it is ambiguous between a constant? If so, is there documentation on this? Or, is it a bug?

user2864740
  • 60,010
  • 15
  • 145
  • 220
sawa
  • 165,429
  • 45
  • 277
  • 381
  • I never had found anyone, who can ask *such a great conceptual question* like you. You are great! Thanks for sharing this. – Arup Rakshit May 07 '14 at 09:29
  • Sawa, what's wrong, if anything with http://japanese.stackexchange.com/q/15869/91 ? – Andrew Grimm May 11 '14 at 07:19
  • @AndrewGrimm I don't see anything wrong in the question you linked, but I also don't see any relevance of the last sentence in that question to the rest of your question. And although nothing is wrong with it, the question does not seem to make any sense. It is like asking why your name is not written in italics instead of upright. – sawa May 11 '14 at 07:30
  • @sawa I've edited the question. How does it look now? – Andrew Grimm May 11 '14 at 07:40
  • @AndrewGrimm I see. Now it makes sense. By the way, the English Wikipedia that you cited seems contradictory, and looks different from what the Japanese one says. If it is a name (a proper noun) as the both versions say, then it cannot be an onomatopoeia as the English version says (even though it may be derived from an onomatopoeia, which only the inventor of that name knows). – sawa May 11 '14 at 07:44
  • @sawa In future, unless I say otherwise, it's ok for you to post comments on one of my Stack Overflow posts about my questions, answers, comments or chat messages from the Japanese Language Stack Exchange. – Andrew Grimm May 11 '14 at 08:14
  • @AndrewGrimm I am not interested in doing that. – sawa May 11 '14 at 08:14
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/52452/discussion-between-andrew-grimm-and-sawa) – Andrew Grimm May 11 '14 at 08:16

1 Answers1

7

The thing is that this actually isn't ambiguous — it's just not intuitive. In Ruby's grammar, an identifier that starts with a capital letter and isn't followed by an argument list is always parsed as a constant lookup.

You would get the same error even if you had defined a method like def Foo "You won't see this" end. When it encountered Foo, it would still try to look up the constant Foo and throw a NameError when no constant by that name was found. In order to call a method that starts with a capital letter, you have to include an explicit receiver (e.g. self.Foo) or an argument list (if only an empty one).

user2864740
  • 60,010
  • 15
  • 145
  • 220
Chuck
  • 234,037
  • 30
  • 302
  • 389