Given a string '123', I can create a Float or Integer:
x = Float('123.45')
y = Integer('123')
As an exercise in dynamic typing, I want to extend Numeric, the top-level number class, with a method that converts the number to a string, reverses it, and then back to its original type.
This would allow me to do this:
x = (123).reverse
// x == 321
or this:
y = (54.321).reverse
// y == 123.45
One implementation looks like this: (this works correctly)
class Numeric
def reverse
str = self.to_s.reverse
if self.is_a?(Float)
return Float(str) # or str.to_f
elsif self.is_a?(Integer)
return Integer(str) # or str.to_i
end
end
end
But I want to create the result dynamically rather than checking a list of types. I tried using Class.new():
class Numeric
def reverse
str = self.to_s.reverse
self.class.new(str)
end
end
I thought this would work since I can call Float('123.45') or Integer('123'). However, I get these errors:
irb(main):047:0> (54.321).reverse
NoMethodError: undefined method `new' for Float:Class
from (irb):44:in `reverse'
from (irb):47
from /Users/aaron/.rvm/rubies/ruby-2.1.1/bin/irb:11:in `<main>'
irb(main):048:0> (123).reverse
NoMethodError: undefined method `new' for Fixnum:Class
from (irb):44:in `reverse'
from (irb):48
from /Users/aaron/.rvm/rubies/ruby-2.1.1/bin/irb:11:in `<main>'
So I have two questions:
- How does
Float('123.45')orInteger('123')work if they don't implementnew? - How can I implement
Numeric.reverse()without any conditionals?
I know there are other cases where this won't work (like negative numbers), but I'm not concerned with those issues (yet).
Float::INFINITY. Also a good answer to the first question can be found here.Object#send. But then it still won't work for integers since they're not actually instances ofInteger.