rubyliteralssingleton-methods

Defining methods on instances of Fixnum's


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.


Solution

  • 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