On 08.05.2011 04:54, 7stud -- wrote:
> Bobby S. wrote in post #997293:
>> Thank you so much that helped allot and now I understand threading
>> better.
>>
>> Could you explain the first part?
>> pic_names.collect.with_index do |name, pic_numb|
>>
>> I understand how the threading is working but not the loop. I read
>> .collect returns all elements in an array.  But what about the
>> with_index and adding pic_numb to the iterator.
>
> In ruby 1.9, if you call collect() without supplying a block, you get
> what's called an 'enumerator' back.  It's an object of the class
> Enumerator, which has a method called with_index().  with_index() works
> just like each()--but it sends a second argument to the block: the index
> of the element.
>
> I don't like that collect() loop at all.  collect() returns an array
> containing elements of the original array for which the block evaluates
> to true.

It seems you are confusing #collect with #select here.

irb(main):006:0> a=[true,false,nil,1,2,3]
=> [true, false, nil, 1, 2, 3]
irb(main):007:0> a.collect {|x| x}
=> [true, false, nil, 1, 2, 3]
irb(main):008:0> a.select {|x| x}
=> [true, 1, 2, 3]
irb(main):009:0> a.collect {false}
=> [false, false, false, false, false, false]
irb(main):010:0> a.select {false}
=> []
irb(main):011:0> a.select {true}
=> [true, false, nil, 1, 2, 3]

#collect does the same as #map: it creates a new Array containing the 
result of block evaluation on each element in the original Enumerable.

irb(main):012:0> a.collect {|x| x.inspect}
=> ["true", "false", "nil", "1", "2", "3"]

>  But the only thing inside the block is Thread.new(), which
> always returns something that evaluates to true, so all elements of the
> original array are selected by collect() and returned in a new array,
> which is then discarded because the result of collect() isn't assigned
> to a variable.

That's not true either:

>     pic_names.collect.with_index do |name, pic_numb|
>         Thread.new do
>             print ' . '
>             new_name = batch_name + pic_numb.to_s + ' .jpg'
>             File.rename name, new_name
>         end
>     end.each{ |thread| thread.join }

This creates a thread for each input and then joins on all of them. 
It's perfectly appropriate and even elegant to use #collect here.

irb(main):013:0> a.collect.with_index {|x,y| [x,y]}
=> [[true, 0], [false, 1], [nil, 2], [1, 3], [2, 4], [3, 5]]

With Threads:

irb(main):014:0> a.collect.with_index {|x,y| Thread.new {}}
=> [#<Thread:0x106a8278 run>, #<Thread:0x106a81d0 run>, 
#<Thread:0x106a8160 run>, #<Thread:0x106a80f0 run>, #<Thread:0x106a8048 
run>, #<Thread:0x106a7fbc run>]

Kind regards

	robert

-- 
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/