Rational numbers get normalized on initialization, so you can not know which numbers where given as original arguments. You can also not subclass Rational
to install an initializer of your own, and monkeypatching as you do is not really the optimal way to achieve what you want to achieve (which I think you know).
What you can do is create a proxy around Rational
with BasicObject
which preserves the original arguments and will not disturb normal operation of the original Rational
class
class RationalWithArgumentStore < BasicObject
attr_accessor :original_arguments, :rational
def initialize *args
@original_arguments = args
@rational = Rational *args
end
# Basic Object is a basic object, but defines ==
# so let's overwrite it to route to rational
def == other
@rational == other
end
# Route all unknown method calls to rational
def method_missing meth, *args, &block
@rational.send meth, *args, &block
end
end
def RationalWithArgumentStore(*args)
RationalWithArgumentStore.new(*args)
end
So now you can do
my_rational = RationalWithArgumentStore(2,10)
my_rational.original_arguments #=> [2, 10]
#use it like a normal rational
my_rational * 3
my_rational.truncate