は、私は、次のクラスがあります。RubyでArrayコンストラクタをオーバーライドするにはどうすればよいですか?
class Library < Array
attr_accessor :authors
end
をそして私は著者は、クラスのコンストラクタ内の属性initilize、まだアレイ#新しい動作を使用したいと思います。私はこれを試しました:
しかしそれはエラーをもたらします。
どうすればこの問題を解決できますか?
は、私は、次のクラスがあります。RubyでArrayコンストラクタをオーバーライドするにはどうすればよいですか?
class Library < Array
attr_accessor :authors
end
をそして私は著者は、クラスのコンストラクタ内の属性initilize、まだアレイ#新しい動作を使用したいと思います。私はこれを試しました:
しかしそれはエラーをもたらします。
どうすればこの問題を解決できますか?
したがって、配列スプラット(*
)の代わりにオブジェクトスプラット(**
)を使用しているため、#initialize
オーバーライドが失敗しています。
ただし、これを行うべきではありません。 Rubyのコアクラスをサブクラス化すると、そのクラスの新しいインスタンスを作成するメソッドが多数あり、クラスの新しいインスタンスを作成するために更新されないため、さまざまな直感的な動作につながります。たとえば、Library.new.reverse
とLibrary.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
'Array'からサブクラス化するなら、なぜ' Enumerable'をインクルードする必要がありますか? –
@ jack-nobleはおそらくクラス定義から '
@gmcnaughtonうん、私はサブクラスを削除するつもりだった。申し訳ありません、編集しています。 –
'Array :: new'を' Array :: old_new'にエイリアスしてから、必要に応じて前後するものを実行する新しい 'Array :: new'メソッドを作成することです。 'Array :: old_new'を呼び出します。 –