> -----Original Message----- > From: Ben Tilly [mailto:ben_tilly / hotmail.com] > Sent: Sunday, January 07, 2001 06:25 PM > To: ruby-talk ML > Subject: [ruby-talk:8803] Re: Modules and mixins > > > Ruby also supports functional techniques. You call proc() > to produce a procedure, and then call it many times. The > following quick hack shows what those techniques look like, > though it is a port of a quick example I did in Perl and I > don't know if it is how you would want to solve this problem > in Ruby: > > #! /usr/local/bin/ruby -w > > def nested_for (fn, *arg) > bind_param(fn, *arg)[] > end > > def bind_param(fn, my_range, *more_args) > bound_fn = proc { |*args| > for arg in my_range do > fn[arg, *args] > end > } > (0 == more_args.length()) ? > bound_fn : > bind_param(bound_fn, *more_args) > end > > nested_for \ > proc {|*arg| puts arg.join(" ")} , \ > 1..2, 'a'..'c', 'A'..'D' > Yes, this is a very need solution! Interestingly enough (basically) the same example came up in a very long ``Ruby versus Python'' thread on the python list in the middle of November 2000. The proposed Ruby solution was something along the line of: class MRange def initialize (*a) @len = a.length/2 -1 @lo = a[0.. / len] @up = a[@len+1..2*@len+1] end def each __each(0) {|l| yield l } end private def __each(n) if n == @len (@lo[n]..@up[n]).each { |l| yield [l] } else (@lo[n]..@up[n]).each \ { |l| __each(n+1) {|r| yield [l]+ r }} end end end MRange.new(1,'a','A', 2,'c','D').each \ {|arg| puts arg.join(" ")} The elegance (? probably a matter of taste) of this Ruby solution was dismissed since it is pretty easy to calculate the index of an element in a ``Multi-Range'' directly. (Nobody was public disconcerted that this ``elegant solution'' was probably 3 or 4 times as long). Christoph