What is inject doing here?

Why does this not do what I expect?

irb(main):001:0> RUBY_VERSION
=> “1.9.2”
irb(main):002:0> (0…3).inject {|s, i| a = i%2 == 0 ? 1 : -1; p a}
-1
1
-1
=> -1

I would think the result should be

1
-1
1
-1
=> -1

Todd

The first two elements of the range are the first two elements to be
used as arguments to
the inject block:

First, s = 0, i = 1:

a = 1 % 2 == 0 ? 1 : -1; p a # a = -1

Then, s = -1, i = 2:

a = -1 % 2 == 0 ? 1 : -1; p a # a = 1

Then, s = 1, i = 3:

a = 3 % 2 == 0 ? 1 : -1; p a # a = -1

And the range is exhausted.

Michael E.
[email protected]
http://carboni.ca/

On Thu, Mar 3, 2011 at 2:15 AM, Todd B. [email protected] wrote:

irb(main):002:0> (0…3).inject {|s, i| a = i%2 == 0 ? 1 : -1; p a}
-1
1
-1
=> -1

Why is this done using inject? s is never used in the block, but since
p a
returns nil, s would be nil in every iteration after the first one.

(0…3).map { |n| n % 2 == 0 ? 1 : -1 }.each { |n| puts n }

You could of course just use each by itself:

(0…3).each do |n|
if n % 2 == 0
puts 1
else
puts -1
end
end

I’m pretty sure he’s just trying to understand inject’s behavior on
ranges,
not looking for refactoring advice.

Also, on Ruby 1.9, Kernel#p returns its arguments.

Michael E.
[email protected]
http://carboni.ca/

On Thu, Mar 3, 2011 at 5:46 PM, Michael E. [email protected] wrote:

Also, on Ruby 1.9, Kernel#p returns its arguments.

I forgot about that! :slight_smile: I caught that one recently courtesy of JEG2.