せかいや

いまいるここを、おもしろく http://sekai-in-the-box.appspot.com/

【Ruby】並列イテレーター

プログラミング言語 Ruby

プログラミング言語 Ruby

もうちょっとだ。。。!


並列イテレータ

■mapメソッド並列Ver

module Enumerable
  def conmap(&block)
    threads = []
    self.each do |item|
      threads << Thread.new{block.call(item)}
    end
    p Thread.list
    threads.map{|t| t.value}
  end
end
a = [1,2,3]
p a.conmap{|x| x**x}
p Thread.list

■実行結果

[#<Thread:0x4a9148 run>, #<Thread:0x30ef7f0 run>, #<Thread:0x30ef730 run>, #<Thread:0x30ef688 run>]
[1, 4, 27]
[#<Thread:0x4a9148 run>]


 

並列マップ

module Enumerable
  def concurrently(&block)
    threads = []
    self.each do |item|
      threads << Thread.new{block.call(item)}
    end
    threads.map{|t| t.join}
  end
end
a = [1,2,3]
p a.concurrently{|x| p x*x}

 
■実行結果

1
4
9

 
このコードは以下のように一文で書ける

module Enumerable
  def concurrently(&block)
    self.map{|item| Thread.new{yield(item)}}.each{|t| t.join}
  end
end
a = [1,2,3]
a.concurrently{|x| p x*x}

お断り

yieldを使う3つ目のコードは、本には、引数がない形で書いてあります。
引数で変数名をつけても、それを参照することがないのだから、
当然、引数として定義するのは無駄なこと。
でも個人的には引数が0なわけではないのに、
引数を定義していないのが分かりづらく、、
明示的に(&block)を足しました。