On 11/09/2009 10:24 PM, Judson Lester wrote:
> I completely agree with Jason's diagnosis.  I'd like to make two
> observations, though.
> 
> First, you can avoid the mutex entirely by using thread-local variables:
> 
>   threads << Thread.new { Thread.current[:result] = method1(string) }
> 
>   results = threads.inject({}) do |results, thread|
>     thread.join
>     results.merge(thread[:result])
>   end

Even better: we have Thread.value.  If you join only from a single 
thread there is no additional synchronization needed:

irb(main):001:0> t = (1..5).map {|i| Thread.new(i) {|x| "value #{x}"} }
=> [#<Thread:0x9c4f618 dead>, #<Thread:0x9c4f58c dead>, 
#<Thread:0x9c4f4b0 run>, #<Thread:0x9c4f424 run>, #<Thread:0x9c4f398 run>]
irb(main):002:0> t.map {|th| th.value}
=> ["value 1", "value 2", "value 3", "value 4", "value 5"]

> Second, and (possibly) more controversially, just because you can eval
> doesn't mean you should.  To my eye, this looks nicer:
> 
>   threads = [
>    Thread.new { Thread.current[:result] = method1(string) },
>    Thread.new { Thread.current[:result] = method2(string) },
>    Thread.new { Thread.current[:result] = method3(string) },
>    Thread.new { Thread.current[:result] = method4(string) }
>   ]
> 
> And exception handling, etc, will be ever so much clearer.

You can as well do

def method(string)
   threads = %w{
     methodname1
     methodname2
     methodname3
     methodname4
     }.map do |method|
       Thread.new(method) do |m|
         send(m, string) # each method call makes an HTTP request
       end.map {|th| th.value}
end

and be done.

Kind regards

	robert

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