From: Jamis Buck Date: 2004-09-16T04:27:14+09:00 Subject: Re: Intercepting break within a block after yield Alexey Verkhovsky wrote: > Sorry for posting this without a subject earlier. > > > ------------------------------------------------------------------------ > > Subject: > No Subject > From: > Alexey Verkhovsky > Date: > Thu, 16 Sep 2004 03:50:06 +0900 > To: > ruby-talk@ruby-lang.org (ruby-talk ML) > > To: > ruby-talk@ruby-lang.org (ruby-talk ML) > > > A question from Ruby-Forum: > http://www.ruby-forum.org/bb/viewtopic.php?t=13 > > >>If I do this: >> >>Code: >> >>a = [1, 2, 3] >>a.each do |x| >> puts x >> if x == 2 then break; end >>end >> >>It works (prints 1, 2 then stops), but returns nil. Normally a.each >>should return a. >> >>I need an iterator that will return all elements processed until the >>break. E.g. >> >>Code: >> >>class Array >> def each_with_a_twist >> self.each_with_index do >> |element, index| >> yield element >> >>> INTERCEPT THE BREAK <<< >> break self[0, index] >> end >> end >>end >> >>Is it possible? > > > > I've come up with the following suggestion: > > class A > def a > yield > ensure puts "after block"; return 1 > end > end > > I can see that this code is not good enough, because it doesn't > differentiate between the block terminated by break and the block > terminated by an error. What would be the Ruby Way here? > > Alex > > > > Would something like this work? class Array def each_with_a_twist index = 0 return_list = true self.each_with_index do |element, index| yield element end rescue Exception return_list = false raise ensure return_list and return self[0..index] end end a = [ 1, 2, 3, 4, 5 ] result = a.each_with_a_twist { |i| break "blah" if i > 2 } p result result = a.each_with_a_twist { |i| raise "blah" if i > 2 } p result -- Jamis Buck jgb3@email.byu.edu http://www.jamisbuck.org/jamis "I use octal until I get to 8, and then I switch to decimal."