2016-09-25 6 views
3

は、私は、次のクラスがあります。RubyでArrayコンストラクタをオーバーライドするにはどうすればよいですか?

class Library < Array 
    attr_accessor :authors 
end 

をそして私は著者は、クラスのコンストラクタ内の属性initilize、まだアレイ#新しい動作を使用したいと思います。私はこれを試しました:

しかしそれはエラーをもたらします。

どうすればこの問題を解決できますか?

+0

'Array :: new'を' Array :: old_new'にエイリアスしてから、必要に応じて前後するものを実行する新しい 'Array :: new'メソッドを作成することです。 'Array :: old_new'を呼び出します。 –

答えて

2

したがって、配列スプラット(*)の代わりにオブジェクトスプラット(**)を使用しているため、#initializeオーバーライドが失敗しています。

ただし、これを行うべきではありません。 Rubyのコアクラスをサブクラス化すると、そのクラスの新しいインスタンスを作成するメソッドが多数あり、クラスの新しいインスタンスを作成するために更新されないため、さまざまな直感的な動作につながります。たとえば、Library.new.reverseLibrary.new + Library.newは、ライブラリではなく新しい配列を返します。

代わりに、あなたのクラスで配列インスタンス変数を作成し、そのクラスに委譲することで、適切な動作を得ることができます。 #eachを定義し、すべてのRuby enumerableメソッドを取得できます。必要な配列メソッドを定義することもできます。

class Library 
    include Enumerable 
    attr_accessor :authors 

    def initialize(*args) 
    @authors = {key1: 'val1', key2: 'val2'} 
    @array = args 
    end 

    def each(&block) 
    @array.each(&block) 
    end 

    def [](index) 
    @array[index] 
    end 
end 
+0

'Array'からサブクラス化するなら、なぜ' Enumerable'をインクルードする必要がありますか? –

+2

@ jack-nobleはおそらくクラス定義から ' gmcnaughton

+0

@gmcnaughtonうん、私はサブクラスを削除するつもりだった。申し訳ありません、編集しています。 –

関連する問題