Как Перечислители работают в Ruby 1.9.1?

C++ генерирует конструктора по умолчанию. В случае необходимости (определенный во время компиляции я верю), это также генерирует конструктора копии по умолчанию и конструктора присвоения по умолчанию. Я ничего не услышал о гарантиях обнуления памяти все же.

8
задан the Tin Man 13 September 2011 в 18:54
поделиться

3 ответа

Вот простой перечислитель ruby, который использует волокна и должен вести себя как оригинал:

class MyEnumerator
  include Enumerable

  def initialize(obj, iterator_method)
    @f = Fiber.new do
      obj.send(iterator_method) do |*args|
        Fiber.yield(*args)
      end
      raise StopIteration
    end
  end

  def next
    @f.resume
  end

  def each
    loop do
      yield self.next
    end
  rescue StopIteration
    self
  end
end

И прежде, чем кто-то пожалуется на исключения в качестве управления потоком: настоящий Enumerator также вызывает StopIteration в конце , поэтому я просто эмулировал исходное поведение.

Использование:

>> enum = MyEnumerator.new([1,2,3,4], :each_with_index)
=> #<MyEnumerator:0x9d184f0 @f=#<Fiber:0x9d184dc>
>> enum.next
=> [1, 0]
>> enum.next
=> [2, 1]
>> enum.to_a
=> [[3, 2], [4, 3]]
14
ответ дан 5 December 2019 в 08:24
поделиться

Actually in your e = Bunk.new.each the else clause is not executed initially. Instead the 'if !block_given' clause executes and returns an enumerator object. The enumerator object does keep a fiber object internally. (At least that is what it looks like in enumerator.c)

When you call e.each it is calling a method on an enumerator which uses a fiber internally to keep track of its execution context. This method calls the Bunk.each method using the fibers execution context. The Bunk.each call here does execut the else clause and yields up the value.

I do not know how yield is implemented or how a fiber tracks the execution context. I haven't looked at that code. Almost all of the enumerator and fiber magic is implemented in C.

Are you really asking how fibers and yield are implemented? What level of detail are you looking for?

If I am off base please correct me.

4
ответ дан 5 December 2019 в 08:24
поделиться

Как отмечали другие плакаты, я считаю, что он создает свое собственное частное «волокно» [в 1.9]. В 1.8.7 (или 1.8.6, если вы используете гем backports) так или иначе он делает то же самое (возможно, потому что все потоки в 1.8 эквивалентны волокнам, он просто использует их?)

Таким образом, в 1.9 и 1.8.x, если связать несколько из них вместе a.each_line.map.each_with_index {}

На самом деле он проходит через всю цепочку с каждой строкой, вроде как канал в командной строке

http://pragdave.blogs.pragprog.com/pragdave/2007 /12/pipelines-using.html

HTH.

1
ответ дан 5 December 2019 в 08:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: