C++ генерирует конструктора по умолчанию. В случае необходимости (определенный во время компиляции я верю), это также генерирует конструктора копии по умолчанию и конструктора присвоения по умолчанию. Я ничего не услышал о гарантиях обнуления памяти все же.
Вот простой перечислитель 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]]
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.
Как отмечали другие плакаты, я считаю, что он создает свое собственное частное «волокно» [в 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.