Can anyone explain this code? It uses Inject

def webs
@webs ||= Web.find(:all).inject({}) { |webs, web|
webs.merge(web.address => web) }
end

Chris wrote:

def webs
@webs ||= Web.find(:all).inject({}) { |webs, web|
webs.merge(web.address => web) }
end

Turns an array into a hash with the web address as a key.

Eric

On 7/25/06, Chris [email protected] wrote:

[email protected]
http://lists.rubyonrails.org/mailman/listinfo/rails

@webs ||= # if @webs has a vaule do nothing, if it’s nil then put
whatever
is on the right into @webs

Web.find(:all).inject({}){ |webs, web| webs.merge(web.address => web)}

Inject can be a bit tricky. basically It might be easier to abstract
it.

Inject replaces the cumulative with whatever the block evaluates to each
iteration starting with the inject parameter.

[1,2,3].inject({}) { |cumulative, element| cumulative.merge(
element.to_s =>
element ) }

Walking through this one

Element 1
cumulative = {} (the param in inject
element = 1 (The first element to be iterated over)

evaluate block and replace the cumulative
cumulative = cumulative.merge( element.to_s => element) #=> gives {
‘1’ =>
1 }
end iteration

Element 2
cumulative = { ‘1’ => 1 } - The result of the last iteration
element = 2

evaluate block and replace the cumulative
cumulative = cumulative.merge( element.to_s => element) #=> gives {
‘1’ =>
1, ‘2’ => 2 }
end iteration

Element 3
cumulative = { ‘1’ => 1, ‘2’ => 2 } - The result of the last iteration
element = 3

evaluate block and replace the cumulative
cumulative = cumulative.merge( element.to_s => element) #=> gives {
‘1’ =>
1, ‘2’ =>2, ‘3’ => 3 }
end iteration

and so on.

so in the example you would be building a hash of all the web objects of
the
form
web.address => web

Hope that helps

Thanks… that helped

One other thing to note about the code is that it creates quite a few
hashes, 1 initial hash and one for each element in the array. Using the
more abstract example and irb:

irb(main):001:0> [1,2,3].inject({}) { |cumulative, element| puts
cumulative.object_id; cumulative.merge( element.to_s => element ) }
23135864
23135732
23135648
=> {“1”=>1, “2”=>2, “3”=>3}

Here you can see the object_id is different each time, indicating that
cumulative is different on each interation and therefore a new object.
This can be avoided by using the merge! method that will modify the
cumulative object instead of returning a new Hash on each iteration.

irb(main):002:0> [1,2,3].inject({}) { |cumulative, element| puts
cumulative.object_id; cumulative.merge!( element.to_s => element ) }
23116412
23116412
23116412
=> {“1”=>1, “2”=>2, “3”=>3}

russ.

Rick O. wrote:

On 7/25/06, Chris [email protected] wrote:

def webs
@webs ||= Web.find(:all).inject({}) { |webs, web|
webs.merge(web.address => web) }
end

FYI in edge rails:

def webs
@webs ||= Web.find(:all).index_by &:address
end

Does the ampersand mean anything, or is it a typo?

Joe

On 7/25/06, Chris [email protected] wrote:

def webs
@webs ||= Web.find(:all).inject({}) { |webs, web|
webs.merge(web.address => web) }
end

FYI in edge rails:

def webs
@webs ||= Web.find(:all).index_by &:address
end

On 7/27/06, Joe [email protected] wrote:

def webs
@webs ||= Web.find(:all).index_by &:address
end

Does the ampersand mean anything, or is it a typo?

Joe

Posted via http://www.ruby-forum.com/.


Rails mailing list
[email protected]
http://lists.rubyonrails.org/mailman/listinfo/rails

The ampersand is a Symbol#to_proc. It’s a nice shorcut and basically
says
use the address method on the object passed into the block.

The equivelant is

@webs || Web.find(:all).index_by { |web| web.address }

Does the ampersand mean anything, or is it a typo?

Explanation:

http://blogs.pragprog.com/cgi-bin/pragdave.cgi/Tech/Ruby/ToProc.rdoc

Regards,
Rimantas

http://rimantas.com/

On 27 Jul 2006, at 07:03, Joe wrote:

@webs ||= Web.find(:all).index_by &:address
end

Does the ampersand mean anything, or is it a typo?

It converts the argument to a Proc. You can find everything you need
to know at http://eli.thegreenplace.net/2006/04/18/understanding-ruby-
blocks-procs-and-methods/
(search for “The ampersand (&)” in the article).

Best regards

Peter De Berdt