Hacker News new | ask | show | jobs
by mpd 3276 days ago
I don't believe there's anything that would prevent that in Ruby, though I'm sure the Forth way would be more elegant.
2 comments

Not in the easy way, not with MRI

    $ irb
    2.4.1 :001 > 1.class
     => Integer 
    2.4.1 :002 > class Integer
    2.4.1 :003?>   def 1
    2.4.1 :004?>     2
    2.4.1 :005?>     end
    2.4.1 :006?>   end
    SyntaxError: (irb):3: syntax error, unexpected tINTEGER
    def 1
         ^
    (irb):6: syntax error, unexpected keyword_end, expecting end-of-input
That's not unexpected as small numeric literals are magic in Ruby, for performance reasons.

More evidence:

    2.4.1 :001 > class Integer
    2.4.1 :002?>   define_method(:one) { 1 }
    2.4.1 :003?>   end
     => :one 
    2.4.1 :004 > Integer.one
    NoMethodError: undefined method `one' for Integer:Class
    2.4.1 :005 > Integer.new.one
    NoMethodError: undefined method `new' for Integer:Class
    2.4.1 :006 > Integer.new
    NoMethodError: undefined method `new' for Integer:Class
    2.4.1 :007 > class Klass
    2.4.1 :008?>   define_method(:one) { 1 }
    2.4.1 :009?>   end
     => :one
    2.4.1 :010 > Klass.one
    NoMethodError: undefined method `one' for XY:Class
    2.4.1 :011 > Klass.new.one
     => 1 
So Integer is not like other classes and the actual reason for that http://archive.oreilly.com/pub/post/the_ruby_value_1.html

TLDR MRI gets the value of the number directly from value of the C pointer and saves the lookup. It's a 1 in the lowest bit and the integer value in the others. That's why 0.object_id == 1, 1.object_id == 3, etc

Obviously that's implementation dependent but I guess no Ruby implementation is going us to redefine integers if MRI does not.

The other sites don't seem to have this problem as they compare STDOUT. CodeWars should also do something like this.