2

我如何获得原始数字?例如,当我输入:

r = Rational(2, 10)
# (1/5)

2 和 10 将更改为 1 和 5:

r.numerator   # 1
r.denominator # 5

如何从 Rational 类(r)的实例中获得 2 和 10?

我给 Rational 类打了猴子补丁并创建了新方法(Rational_o):

def Rational_o *args
  x, y = args
  r = Rational *args
  r.x = x
  r.y = y
  r
end

class Rational
  attr_accessor :x, :y
end

它可以工作,但是是否有存储原始 x 和 y 的内置方法或变量?

4

3 回答 3

4

不,没有。归约是有理数归一化的一种基本且常用的方法。为什么有理数会保留原来的分子和分母?它没有任何意义。

您的问题就像问“由"foo" + "bar"(变为"foobar")创建的字符串是否保留原始子字符串"foo""bar"?它们存储在哪里?”

如果您真的想保留原始数字,那么有理数不是您想要的,子类Rational化不是正确的方法。您应该使用包含一对数字的数组。

于 2013-12-21T10:22:05.463 回答
3

有理数在初始化时被规范化,因此您无法知道哪些数字作为原始参数给出。您也不能子类Rational化来安装自己的初始化程序,并且像您一样进行猴子补丁并不是实现您想要实现的目标的最佳方式(我想您知道)。

您可以做的是创建一个代理,Rational使用BasicObject它保留原始参数并且不会干扰原始Rational类的正常操作

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

所以现在你可以做

my_rational = RationalWithArgumentStore(2,10)
my_rational.original_arguments #=> [2, 10]

#use it like a normal rational
my_rational * 3
my_rational.truncate
于 2013-12-21T10:34:29.077 回答
2

不,没有这样的内置私有或公共方法可以做你想做的事。

如果您真的想将原始数字存储在实例方法中,那么您的猴子补丁绝对是其中一种方法。

实际上,方法Rational(a,b)是定义在类之外的实例方法Rational,有点像Array()String()方法。

于 2013-12-21T10:24:04.700 回答