Feature #6824

StopIteration gets a source method

Added by Jan Szumiec over 1 year ago. Updated over 1 year ago.

[ruby-core:46929]
Status:Rejected
Priority:Normal
Assignee:Yukihiro Matsumoto
Category:core
Target version:next minor

Description

=begin
I'd like to add a method to StopIteration that returns an instance of the enumerator which triggered this exception. Eg:

enum = [].each
begin
enum.next
rescue StopIteration => ex
puts "same" if ex.source == enum
end

This is useful when you're merging multiple collections using min/max - when one of the collections is exhausted it can be easily ignored.

enumerators = 100.times.map do
rand(100).times.map do
rand
end.sort.each
end

merged = []
while !enumerators.empty?
begin
enumerators.map(&:peek)
values = enumerators.map(&:next)

  merged += values.sort
rescue StopIteration => e
  enumerators.delete(e.source)
  retry
end

end

fail unless merged != merged.sort

Attached is a patch against trunk.
=end

stop.patch Magnifier (2.32 KB) Jan Szumiec, 08/02/2012 06:45 PM

History

#1 Updated by Nobuyoshi Nakada over 1 year ago

  • Description updated (diff)

=begin
You should use (({assertsame})) instead of (({assertequal})), I think.
=end

#2 Updated by Dominic Sisneros over 1 year ago

I use the following method to weave enumerators together

#Intersperse several iterables, until all are exhausted
def weave(*enumerators)
enums = enumerators.map{|e| e.toenum}

result = Enumerator.new do |y|

while !enums.empty?
loop
enum = enums.dup
loopenum.eachwithindex do |enum,i|
begin
y << enum.next
rescue StopIteration
#raise StopIteration if enums.empty?
enums.delete
at(i)
end
end
end
#raise StopIteration
end
end

#3 Updated by Koichi Sasada over 1 year ago

  • Assignee set to Yusuke Endoh

mame-san, could you judge this ticket?

#4 Updated by Yusuke Endoh over 1 year ago

  • Status changed from Open to Rejected
  • Assignee changed from Yusuke Endoh to Yukihiro Matsumoto
  • Target version changed from 2.0.0 to next minor

Hello,

jasiek (Jan Szumiec) wrote:

This is useful when you're merging multiple collections using min/max - when one of the collections is exhausted it can be easily ignored.

You are misunderstanding merge sort.
Your example does never work as intended.

fail unless merged != merged.sort

I bet this condition is inverted.

The proposal itself might be useful, but this ticket is based on misconception.
So I'm closing it. Please open another one if you wish.

Yusuke Endoh mame@tsg.ne.jp

Also available in: Atom PDF