From: Robert Klemme Date: 2005-10-27T17:22:08+09:00 Subject: Re: Enumerable#build Eric Hodel wrote: > On Oct 26, 2005, at 4:47 AM, Robert Klemme wrote: > >> Martin DeMello wrote: >> >>> class Enumerable >>> def build(seed) >>> each {|i| >>> seed.add(yield i) >>> } >>> end >>> end >>> >>> and >>> >>> Array#build == Array#<< >>> Hash#build(k,v) == Hash#[] >>> etc >>> >>> So you could say [1,2,3].build({}) {|i| [i, 1]} for the question >>> that prompted the to_hash thread, but also, in general, you can >>> collect into non-array structures (binary trees, e.g.) as long as >>> they implement a suitable #add method. >>> >>> (Of course, you can do ary.inject(seed) {|i| seed.add(f(i)); seed} >>> right now but a #build method makes the common case pretty.) >>> >> >> Looks good. But, >> >> - Enumerable is a module... :-) >> >> - You should add seed as return value. >> >> - Your first example won't work as Hash#add is nonexistent >> >> An alternative approach would be to reverse the logic and have >> Enumerable#populate: >> >> module Enumerable >> def populate(*enum) >> enum = enum.first if enum.size == 1 >> enum.each {|*a| add(yield(*a))} >> self >> end >> end >> >> class Hash >> def populate(*enum) >> enum = enum.first if enum.size == 1 >> enum.each {|*a| send(:[]=, *yield(*a))} >> self >> end >> end >> >> >>>> h={}.populate(1,2,3) {|x| [x, "val #{x}"]} >>>> >> => {1=>"val 1", 2=>"val 2", 3=>"val 3"} >> >> What do you think? > > I think you have too much magic. Is this good or bad? :-)) > Enumerable#to_a, Array#fill, Array#flatten and Hash::[] do this > pretty handily and much more cleanly: > > Hash[*ary.fill { |i| [i, "val #{i}"]}.flatten] > > $ ruby -e 'p Hash[*(0..3).to_a.fill { |i| [i, "val #{i}"] }.flatten ]' > {0=>"val 0", 1=>"val 1", 2=>"val 2", 3=>"val 3"} I'm not sure about cleanness but this is certainly less memory efficient as it creates relatively large temporary data structures. Kind regards robert