在ruby中对Fixnum进行子类化

时间:2009-07-08 01:57:42

标签: ruby inheritance

所以我理解你不应该直接将Fixnum,Float或Integer子类化,因为它们没有#new方法。使用DelegateClass似乎工作,但它是最好的方法吗?有谁知道这些课没有#new的原因是什么?

我需要一个类似Fixnum的类,但有一些额外的方法,我希望能够从类中通过self引用它的值,例如:

class Foo < Fixnum
  def initialize value
    super value
  end

  def increment
    self + 1
  end
end

Foo.new(5).increment + 4 # => 10

3 个答案:

答案 0 :(得分:17)

您可以自己轻松设置快速转发实现:

class MyNum
  def initialize(number)
    @number = number
  end

  def method_missing(name, *args, &blk)
    ret = @number.send(name, *args, &blk)
    ret.is_a?(Numeric) ? MyNum.new(ret) : ret
  end
end

然后你可以在MyNum上添加你想要的任何方法,但你需要在这些方法中使用@number,而不是直接调用super。

答案 1 :(得分:4)

IIRC,Ruby的主要实现将Fixnums存储为立即值,使用该字的一些低位将其标记为Fixnum而不是指向堆上对象的指针。这就是为什么在32位机器上,Fixnums只有29位(或者不管它是什么)而不是一个完整的单词。

因此,您无法将方法添加到Fixnum的单个“实例”中,也无法将其子类化。

如果你没有设置“类似Fixnum”的类,你可能必须创建一个具有Fixnum实例变量的类,并正确调用forward方法。

答案 2 :(得分:2)

你能不扩展FixNum本身?像...

class Fixnum
  def even?
    self % 2 == 0
  end
end

42.even?