inject does not inject last value

P

Peña, Botp

Hi All,

inject is a powerful method in ruby. but the ff gives me surprise..

irb(main):001:0> sum=3D0
=3D> 0
irb(main):002:0> [1,2,3,4,5].inject{|sum,e| sum+e }
=3D> 15
irb(main):003:0> sum
=3D> 10
irb(main):004:0>
irb(main):006:0> RUBY_VERSION
=3D> "1.8.5"
irb(main):007:0> prod=3D1
=3D> 1
irb(main):008:0> [1,2,3,4,5].inject(1){|prod,e| prod*e }
=3D> 120
irb(main):009:0> prod
=3D> 24

it seems that inject does not update accumulator (sum or prod in =
examples) on last iteration.

tested on windows and linux.

kind regards
 
G

Gregor Kopp

irb(main):001:0> sum = [1,2,3,4,5].inject{|sum,e| sum+e}
=> 15
irb(main):002:0> sum
=> 15
 
G

Gregor Kopp

Gregor said:
irb(main):001:0> sum = [1,2,3,4,5].inject{|sum,e| sum+e}
=> 15
irb(main):002:0> sum
=> 15

First you see the Return Value (15), but bevor assign the return value
to sum sum will be 10 and not the return value of the operation itself.
i cannot teach, im a dumpass english loser.
 
R

Ryan Davis

Hi All,

inject is a powerful method in ruby. but the ff gives me surprise..

irb(main):001:0> sum=3D0
=3D> 0
irb(main):002:0> [1,2,3,4,5].inject{|sum,e| sum+e }
=3D> 15
irb(main):003:0> sum
=3D> 10

Inject is just an iterator:

% echo "sum=3D0; [1,2,3,4,5].inject{|sum,e| sum+e }" | parse_tree_show =
-f

[[:lasgn, :sum, [:lit, 0]],
[:iter,
[:call,
[:array, [:lit, 1], [:lit, 2], [:lit, 3], [:lit, 4], [:lit, 5]],
:inject],
[:masgn,
[:array,
[:lasgn, :sum], # <<<<<
[:dasgn_curr, :e]]],
[:call, [:lvar, :sum], :+, [:array, [:dvar, :e]]]]]

Because sum was assigned initially outside of the inject, it is an =20
lvar (local variable) instead of a dvar (dynamic/iter var, like e). =20
You'll notice that the assignments to both of those variables happens =20=

before the call, and is part of the iteration mechanics itself. There =20=

is no assignment done at the end of an iteration.

I think it is more important to point out that inject is =20
_just_another_iterator_. There is nothing special about it or how it =20
works. It is just a simple each just like everything else in =20
Enumerable. This makes the ruby implementation cleaner and easier to =20
maintain. Sum isn't an accumulator, as much as it is just another =20
variable. Should map or reject have some special semantics attached =20
to their block variables?

If you really are stuck on this idea, you can always change "sum+e" =20
to read "sum+=3De" but at that stage, why use an inject at all?

Here is our implementation from metaruby:

def inject(memo =3D :_nothing)
enum =3D self.to_a.dup

memo =3D enum.shift if memo =3D=3D :_nothing

return memo if enum.empty?

enum.each do |item|
memo =3D yield memo, item
end
return memo
end
 
P

Peña, Botp

fr Ryan:
[snipped cool samples]
# Because sum was assigned initially outside of the inject, it is an =20
# lvar (local variable) instead of a dvar (dynamic/iter var, like e). =20
# You'll notice that the assignments to both of those variables=20
# happens =20
# before the call, and is part of the iteration mechanics=20
# itself. There =20
# is no assignment done at the end of an iteration.
#=20
# I think it is more important to point out that inject is =20
# _just_another_iterator_. There is nothing special about it or how it =20
# works. It is just a simple each just like everything else in =20
# Enumerable. This makes the ruby implementation cleaner and easier to =20
# maintain. Sum isn't an accumulator, as much as it is just another =20
# variable. Should map or reject have some special semantics attached =20
# to their block variables?
#=20
# If you really are stuck on this idea, you can always change "sum+e" =20
# to read "sum+=3De" but at that stage, why use an inject at all?
[snipped code explanation]

Hi Ryan, thank you for the very detailed and enlightening explanation. I =
apologize for being too dumb on this inject stuff (<banging head>).

kind regards -botp
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top