7

横断しようとしている木があります。それをたどると、各列挙子がツリーの子を列挙するために使用される列挙子のスタックを保持します。

この列挙子のスタックを複製して別のオブジェクトに渡して、スタックの状態によって示される場所からツリーをトラバースできるようにしたいと考えています。

Enumerator で #dup を呼び出そうとすると、エラーが発生します。列挙子を複製することは可能ですか? そうでない場合、どうすれば同じことを達成できますか? (整数のスタックをインデックスとして考えましたが、効率が心配です。

ここに私が見ているものを示すためのいくつかのコードがあります...

最初の列挙子が開始されると、それを複製することはできません。それが私の状況です。

a = [1,2,3].each
 => #<Enumerator: [1, 2, 3]:each> 
a.next
 => 1 
b = a.dup
TypeError: can't copy execution context
    from (irb):3:in `initialize_copy'
    from (irb):3:in `initialize_dup'
    from (irb):3:in `dup'
    from (irb):3
4

3 に答える 3

1

clone代わりに使用してください:

e1 = [1,2,3].each
e1.dup # TypeError: can't copy execution context
e2 = e1.clone
e1.next #=> 1
e2.next #=> 1
于 2015-09-11T18:09:45.540 に答える
1

独自の列挙子クラスを実装します。

内部カウンターをインクリメントする以外に、列挙子にはあまり魔法はありません。

class MyArrayEnumerator
  def initialize(array)
    @ary,@n=array,0
  end
  def next
    raise StopIteration if @n == @ary.length
    a=@ary[@n];@n+=1;a
  end
end

class Array
  def my_each
    MyArrayEnumerator.new(self)
  end
end

a = [1,2,3].my_each # => #<MyArrayEnumerator:0x101c96588 @n=0, @array=[1, 2, 3]>
a.next # => 1
b = a.dup # => #<MyArrayEnumerator:0x101c95ae8 @n=1, @array=[1, 2, 3]>
a.next # => 2
b.next # => 2
于 2012-11-29T09:59:13.750 に答える