2013-12-18 14 views
6

我可以很容易地从,比如继承,String例如,像这样:如何从Rational继承(或任何没有构造函数的类)?

class MyString < String 
    def stuff 
    self + ' and stuff' 
    end 
end 

# This works: 
MyString.new('things').stuff # => 'things and stuff' 

但我怎么可以从Rational继承,它没有构造?例如:

def MyRat < Rational 
    def inc 
    self + 1 
    end 
end 

# I have tried to initialize like this: 
MyRat.new(10).inC# => NoMethodError: undefined method `new' for MyRat:Class 
MyRat(10).inC# => NoMethodError: undefined method `MyRat' for main:Object 
MyRat.send(:initialize, 10).inc # => TypeError: already initialized class 
# ??? 
# None of it works! 

我找不到初始化我的新类的方法。

+0

为什么不写你自己的'#initialize'方法? –

+0

@ArupRakshit我不能。我会怎么做? – Doorknob

回答

5

您可以将自己的对象定义为Rational的代理。

class MyRat < BasicObject 
    def initialize(value) 
    @rational = Rational(value) 
    end 

    def inc 
    @rational + 1 
    end 

    def method_missing(name, *args, &block) 
    @rational.send(name, *args, &block) 
    end 
end 

将使用类中定义的方法,否则该类将委托给合理实例。

r = MyRat.new(10) 

# MyRat#inc is used 
r.inc 
# => (11/1) 

# to_int delegates to Rational 
r.to_int 
# => 10 

的,因为数值没有初始化的部分解释是this thread

在C代码寻找可用的,我看到新的()中的数值存在和Float, 但它是专门除去: rb_cInteger = rb_define_class(“Integer”,rb_cNumeric); rb_undef_alloc_func(rb_cInteger); rb_undef_method(CLASS_OF(rb_cInteger),“new”);

#....and for floats.. 
rb_undef_alloc_func(rb_cFloat); 
rb_undef_method(CLASS_OF(rb_cFloat), "new"); 

ruby​​源代码不包含删除新的解释。这就是为什么我想知道这背后的推理是什么。它确实不是在Ruby解释器中的技术限制。 目前,它对我来说没有多大意义。

,究其原因是因为

这是一个内部优化。 Fixnums不一定要被创建,并且它们不需要GC'ed。这要比使用普通对象(至少对于Fixnums)更快地使数学运算速度更快 。

本文解释了其他建议和替代方案The Complete Numeric Class

+0

这应该可行,但我很好奇为什么你不能从'Rational'继承。 –

+0

谢谢,我正在尝试这个... – Doorknob

+0

你必须undef所有的方法['BasicObject'](http://www.ruby-doc.org/core-2.0.0/BasicObject.html)提供:'eql?'和'=='和'!=' –