2013-12-18 9 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コードを見てみるで提供され、I)は、(新たな数値に存在することを見ると、 フロートが、それは、具体的に除去されます: rb_cInteger = rb_define_class( "整数"、rb_c数値); 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インタプリタの技術的な制限ではないようです。 現在、それは私にはあまり意味がありません。

と理由それは内部の最適化だ

ためです。フィックスナムは作成する必要はなく、 をGCしなくてもかまいません。これは、通常のオブジェクト(少なくともFixnumsの場合)と比べて、より高速に計算するための長い道のりです。

この記事では、The Complete Numeric Classについてさらに説明します。

+0

これはうまくいくはずですが、なぜ私が 'Rational'から継承できないのかは非常に不思議です。 –

+0

ありがとう、私は今これを試しています... – Doorknob

+0

すべてのメソッド['BasicObject']をundefする必要があります(http://www.ruby-doc.org/core-2.0.0/BasicObject.html) 'eql?'と '=='と '!='を提供します –

関連する問題