From: Florian Frank Date: 2002-11-16T01:20:11+09:00 Subject: Re: ruby-dev summary 18613-18710 On 2002-11-15 21:37:46 +0900, dblack@candle.superlink.net wrote: > No, I mean the actual return value of the method call, which is a > separate matter from the block. In your example, if there were no > block, the return value would be different. In other words, given: > > n = [a,b,c].zip > m = [a,b,c].zip { |x,y,z| x*y+z } > > n and m would not be the same. That's where I'm scratching my head > and wondering if that's the best way. The first case is equivalent to the second case with the block { |*tuple| tuple }. If no block is given, zip just uses the array of parameters of this block. In fact that's exacly the way I implemented zip and unzip while converting some Haskell functions into Ruby. Haskell has zip, zip3, zipWith and zipWith3 and all of this functions can be replaced by a single Ruby method which even can do zipWithN: module Enumerable def zip(&block) block ||= lambda { |*tuple| tuple } size = nil map { |x| x.size }.each do |s| size ||= s s == size or raise "zip with unequal length lists" end result = [] i = 0 catch(:stop) do tuple = [] each do |l| l[i] or throw :stop tuple << l[i] end result << block.call(*tuple) i += 1 redo end result end def unzip(&block) block ||= lambda { |*tuple| tuple } result = [] size = nil each do |x| tuple = block.call(*x) i = 0 size ||= tuple.size size == tuple.size or raise "unzip with unequal length pairs" tuple.each do |t| (result[i] ||= []) << t i += 1 end end result end end To implement this in C is unfortunately a bit more difficult, I fear. -- Programs must be written for people to read, and only incidentally for machines to execute. -- Abelson/Sussman, "The Structure and Interpretation of Computer Programs"