On Wednesday 25 November 2009 10:49:31 am Kirk Haines wrote: > On Wed, Nov 25, 2009 at 9:29 AM, Aldric Giacomoni <aldric / trevoke.net>wrote: > > Ralph Shnelvar wrote: > > > y=0 > > > 1_000_000.times {|x| y+=x} > > > > y = (1..1_000_000).inject { |a, b| a + b } > > > > More idiomatic, though maybe yours is easier to read at first. > > Ugh. His, while wrong for what he is trying to do (sum from 1 to 1000000) > is vastly superior to using inject like that. It's not idiomatic. It's > obtuse. I find this is actually significantly easier to read, though it's probably because I've been doing it for awhile: (1..1_000_000).inject(&:+) I'd much rather have a #sum method on enumerable, but that's almost as concise, though it takes a bit to explain why it works. But even spelling it out, it's pretty clear if you use descriptive variables: (1..1_000_000).inject{|sum, i| sum + i} I don't think that's less readable, except for the fact that you have to understand how inject works. > inject has no advantage with regard to > either execution speed or object creation But it does have the theoretical advantage of fitting exactly the map/reduce pattern -- inject _is_ reduce, by definition and by alias. It's overkill here, and I'm probably over my head, but my understanding of why map/reduce is efficient: In theory, map lets you spread your dataset to up to n machines, where n is the number of items in your dataset, and let each machine perform whatever calculation was called for in the map. Once you've already done that, reduce makes sense -- have each machine perform the reduce (inject) function, passing the result to the next machine, rather than having to aggregate the result of the map into a single location. In reality, none of this really applies to Ruby, at least not to the standard map/inject methods. But it's worth thinking about, and probably good practice for the manycore monstrosities of the future.