From: Robert Klemme Date: 2011-05-08T19:55:35+09:00 Subject: Re: Threading Loops 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 {}} => [#, #, #, #, #, #] Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/