From: Josh Cheek Date: 2010-12-28T06:16:47+09:00 Subject: Re: inject issue --0016e68db81c75ecf704986ada91 Content-Type: text/plain; charset=ISO-8859-1 On Mon, Dec 27, 2010 at 11:25 AM, jzakiya wrote: > On Dec 27, 4:23 am, Ryan Davis wrote: > > On Dec 27, 2010, at 00:55 , Skye Shaw!@#$ wrote: > > > > >> Is this a bug, or is this the expected operation? > > > > > Expected, though it's an odd way to require libs. Use %/ap > > > mathn .../.each { |lib| require lib } > > > > Even better, use simple code for simple problems: > > > > require "ap" > > require "mathn" > > # ...etc... > > > > It REALLY isn't cleaning anything up to use enumeration there. > > I was wondering why these are equivalent: > > a=(1..100).inject :+ > b=(1..100).inject 0, :+ > > but these aren't > > %w/lib1 lib2 lib3/.inject :require > %w/lib1 lib2 lib3/.inject 0, :require > The point of inject is to push some value through all of the elements. You just want to iterate over them, which is the #each method. Since inject wants to push something through the elements, you have to give it the initial value of the object to push through. In your second example, you give zero for the initial value. In the one before that, you do not give it zero. This causes it to use the first element. Then it invokes the plus on that element, and passes the next element. The result is then pushed through for the next iteration. So when you try injecting with numbers and plus, you get (1..3).inject(0,:+) expands to (((0+1)+2)+3) (1..3).inject(:+) expands to ((1+2)+3) Which have the same value. But when you try that with require, you get %w/lib1 lib2 lib3/.inject(0, :require) expands to (((0.require 'lib1').require 'lib2').require 'lib3') %w/lib1 lib2 lib3/.inject(:require) expands to (('lib1'.require 'lib2').require 'lib3') Which doesn't even make sense. require belongs to Kernel, and we want to invoke it as if it were a function, not a method on 0 or the string "lib1" or the boolean value that would be returned if require were properly executed. So you can see that inject is about repeatedly passing the next element to the result of the previous, using the specified method. Thus some value gets "pushed through" (at least that is how I think about it in my brain), but you are just trying to pass each element to the require "function". For that, you would use each, and pass a block instead of a symbol. %w(lib1 lib2 lib3).each { |lib| require lib } --0016e68db81c75ecf704986ada91--