Jano Svitok
1/11/2007 11:20:00 PM
On 1/11/07, Mike Harris <GENIE@prodigy.net> wrote:
> Dominic Son wrote:
>
> >Hi. Hopefully you will see the code and see what I'm trying to do, and
> >see the problem. The loop seems messy, but my method to help with eye
> >strain is to match up the do-end's down an imaginary column... ie:
> >
> >array.each # do # |i|
> > puts i # # <-imaginary column
> > # end #
> >
> >##### So here's the code. ###########
> >
> >def foo(argument1, argument2) #1
> >user = [2,5]
> >
> >user.each do |bar|
> >output = [] #2
> >argument1.each do |i| #3
> >
> > if i.parent.id == bar.id #4
> > output << i.parent.name
> > end
> > end
> >
> > argument2.each do |i|
> > if i.parent.id == bar.id
> > output << i.name
> > end
> > end
> >return output
> > end
> >
> >Comments:
> >#1 - argument comes in as arrays
> >#2 - let's setup the var that will return the array of collected data
> >#3 - i think this is where the problem may lie.
> >#4 - parent is an acts_as_tree method inside rails, just grabs the
> >parant.
> > notice how i call the iterating variable 'bar' inside this new
> >loop..is this legal?
> >
> >My intuition tells me there's probably a better method to do this. Any
> >comments, suggestions would be appreciated.
> >
> >Dominic
> >
> >
> >
> First, your code is missing an end. Second, making the end to the block
> start is easy with the standard convention
>
> This is infinitely easier (to me, and 99.9% of programmers) than moving
> the end out to match the do. Do you find this hard to read? You seem
> to have no problem matching the end to its matching if.
1. The main question: is this legal - yes, it's perfectly legal, it's
one of the blocks' features. The blocks are closures, i.e. they keep
they outer context. This is used when you pass a block between
functions:
def fun2
yield 10
end
def fun1
a= 5
puts fun2 do |i| # yield 10 will set i=10
i + a # here block has access to a even though it is called from fun2
end # => 15
end
2. few changes to the code:
(I changed bar.id to just bar - it seems to me that's what you want)
def foo(argument1, argument2)
user = [2,5]
output = []
user.each do |bar|
output += argument1.select{|i| i.parent.id == bar}.map{|i|
i.parent.name}
output += argument2.select{|i| i.parent.id == bar}.map{|i| i.name}
end
output
end
see Enumerable#select, Enumerable#map for explanation.
shortly: "from argument1 array select those that fulfill the condition
and for each of them get i.parent.name"