2

コレクションを含むクラスがあることがよくあります。外部コードでこのコレクションを反復処理できるようにしたいのですが、変更しないでください。

私は次のようなものを書くことになります:

def iter
  @internal_collection.each do |o|
     yield o
  end
end

これにより、外部コードで次のことが可能になります。

object.iter do |o|
    do_something(o)
end

「iter」メソッドを書くためのより洗練された方法がなければなりません。何か案は?

4

3 に答える 3

2

Enumeratorエレガンスの前に、ブロックが指定されていない場合は必ず返すようにします。

このようにして、ユーザーは行うことができますobject.iter.with_index do |obj, i|

これを行う簡単な方法は、コードを次のように短縮することです。

def iter(&block)
  @internal_collection.each(&block)
end

他の状況では、単にコピーを返したいと思うかもしれません...

def collection
  @internal_collection.dup
end
于 2012-11-27T05:56:31.343 に答える
1

メソッドを明示的に書く限り、それはそれが得るのと同じくらい簡単です。しかし、あなたが求めているのはForwardableモジュールだと思います。コードは次のようになります。

require 'forwardable'

class YourClass
  extend Forwardable
  def_delegator :@internal_collection, :each, :iter
end

または、必要に応じて、Enumerableプロトコル全体を内部コレクションに委任し、内部コレクションが特徴とするすべての標準のEnumerable動作を取得できます。

class YourClass
  extend Forwardable
  def_delegators :@internal_collection, *Enumerable.instance_methods
end
于 2012-11-27T06:22:35.160 に答える
0

dupあなたの内部コレクションでandを使用freezeしてから、それを世界に公開します。

def collection
  @internal_collection.dup.freeze
end

collection.map!(&:to_s) #=> raise RuntimeError: can't modify frozen Array
于 2012-11-27T06:34:27.027 に答える