2009-07-08 46 views
7

所以我明白你不应该直接子类为Fixnum,Float或Integer,因为它们没有#new方法。使用DelegateClass似乎工作,但它是最好的方式?任何人都知道这些类没有#new的原因是什么?红宝石子类别Fixnum

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

class Foo < Fixnum 
    def initialize value 
    super value 
    end 

    def increment 
    self + 1 
    end 
end 

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

告诉我们你真正想要做什么(最终目标),我们会尽力告诉你最好的方法。我不认为在这里分类是合适的。 – 2009-07-08 02:05:51

+0

更新了问题。 – cloudhead 2009-07-08 02:12:34

回答

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操作,而不是能够直接呼叫超级。

2

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

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

42.even? 
+1

我可以,但我宁愿不。此外,Fixnum没有#new,我需要能够为#initialize添加功能。 – cloudhead 2009-07-08 02:19:49

+1

应该小心使用猴子修补。污染Ruby核心类只是为了特定用例,可能会很危险。 – 2014-01-15 14:52:44

4

IIRC,主要的Ruby实现门店Fixnums作为直接值的,使用一些字的低位,以它作为标记一个Fixnum,而不是一个指向堆上的对象。这就是为什么在32位机器上,Fixnums只有29位(或其它),而不是全字。

因此,您不能将方法添加到Fixnum的单个“实例”中,并且无法对其进行子类化。

如果你对具有“Fixnum -like”类的问题已经死气沉沉,那么你可能必须创建一个具有Fixnum实例变量的类,并适当地转发方法调用。