1

I can define a method on an instance like this:

object = Object.new
def object.foo
  puts "5"
end

Trying something similar with a Fixnum doesn't work:

def 3.foo
  puts "3"
end

def 3.foo
     ^
(irb):7: syntax error, unexpected keyword_end, expecting end-of-input

What's the reason for this?

I know this is something I should never do. I'm just wondering why this doesn't work like I expected it to.

sawa
  • 165,429
  • 45
  • 277
  • 381
Nat
  • 890
  • 3
  • 11
  • 23
  • doesn't explain the syntax error, but see [why-cant-singleton-methods-be-defined-on-symbols-or-fixnums](https://stackoverflow.com/questions/13962147/why-cant-singleton-methods-be-defined-on-symbols-or-fixnums) – max pleaner Jul 09 '17 at 20:58
  • It *does* however explain why no-one cares about that syntax error. – Jörg W Mittag Jul 09 '17 at 21:39
  • 1
    Note that the two snippets aren't 100% identical. If you simply change the first line of the first snippet to `object = 3`, you would have a more fair comparison (since you only changed one single thing, you know for a fact that every behavior you see will be due to only this one change), and you would also get a very different and much more sensible error. – Jörg W Mittag Jul 09 '17 at 21:45

1 Answers1

5

There are two things at play here.

One thing is that Fixnums can't have singleton methods. But, we aren't even at that point yet, since your code has a syntax error, and thus Ruby doesn't even attempt to run it in the first place.

The second thing is that Ruby's syntax is complex, and thus there are many dark corner cases. You seem to have found one, where the differing uses of the . symbol to mean both a decimal separator and a method selector conflict with each other in mysterious ways.

Now, of course, this isn't actually much of a problem, since, as I mentioned earlier, Fixnums can't have singleton class anyway:

object = 3

def object.foo
  puts "3"
end
# TypeError: can't define singleton
Jörg W Mittag
  • 363,080
  • 75
  • 446
  • 653