On 6/10/07, Robert Klemme <shortcutter / googlemail.com> wrote:
> > x.call(*%w[cats dogs ones twos threes]) do |*words|
> >  puts words.last # output: thre
> > end
>
> Why do you need x here?  Do you need to pass it around?  Can you show a
> bit more of the picture?

I ended up refactoring, but earlier I was parsing some text by
associating an array of attributes (like, [/a/, /b/, /c$/] that might
match the first 3 words) with a block that processed the matching
text, and then moved the position in the string forward by 3 words. I
tried wanted to be able to do this like:

match = proc do |*regexs|
  if words[position..position+regexs.size] match given regexs
    parsed << yield *words[ .. ]
  end
end

words = %w[the quick brown egg jumped under the slow zebra]
parsed = []

while position < words.size
  match.call(//, /ed/, //) do {|a, b, c| "#{a} #{b.upcase} #{c}" }
  match.call(/the/, //) do {|a, b| "the #{b.upcase}" }

  # increment position somewhere, maybe in match..? this was messy
end

# parsed => [the QUICK brown egg JUMPED under the SLOW zebra]

# where the matched strings were "the quick", "egg jumped under"
#   and "the slow"

Anyway, it turned out that was messy even if I didn't have trouble
passing a block. Instead I made a method scanner(*regexs, &block) that
stores everything in an array, then later another method runs through
the list and does the actual work, where it keeps track of the
position and knows if it made a match or not. Should've slept on it
before I mailed the list!

> There is no other compatible way than to explicitly pass a lambda / proc
> as argument in 1.8.x:

I forgot about passing a lambda/proc as a "normal" parameter... that
would've worked though the syntax isn't as cute.

Thanks for your help Robert and Axel!