【Ruby】rescueの優先順位、並列実行、メソッドのブロック、aliasキーワードを使った既存メソッドの拡張
この本を読んでいます。
- 作者: まつもとゆきひろ,David Flanagan,卜部昌平(監訳),長尾高弘
- 出版社/メーカー: オライリージャパン
- 発売日: 2009/01/26
- メディア: 大型本
- 購入: 21人 クリック: 356回
- この商品を含むブログ (124件) を見る
以下、気がついたことなど。
rescue、代入演算子、ifの優先順位
# メソッドが例外を起こしたらy=0 y = factorical(x) rescue 0
優先順位が高い、というのは「先に評価される」という意味。
y = (factorical(x) rescue 0)
こういうイメージ。
「ifは代入演算子よりも優先順位が低い」とは
(y=5) if a == 0
こういうイメージ。
ifは修飾子であり演算子ではないので(y=5)が最初に実行されることはない。
if修飾子は、後ろを先に評価する。
並列実行、メソッドのブロック
Thread.newでスレッドを生成できる。
本のコードを元に、スレッドあり/なしで2メソッド書いてみる。
def readfiles_threads(filenames) threads = filenames.map do |f| Thread.new do File.read(f) p "start + #{f}" end end p "main thread readfiles_threads" threads.map{ |t| t.value } p "after" end def readfiles(filenames) files = [] filenames.each do |f| files << File.read(f) p "start + #{f}" end p "main thread" end dir = File.dirname(__FILE__) filenames=[ dir+"/test1.txt",・・・ dir+"/test7.txt", ] readfiles_threads(filenames) p "---------------------" readfiles(filenames)
■実行結果
"main thread readfiles_threads" "start + C:/test/test4.txt" "start + C:/test/test2.txt" "start + C:/test/test1.txt" "start + C:/test/test3.txt" "start + C:/test/test5.txt" "start + C:/test/test6.txt" "start + C:/test/test7.txt" "after" "---------------------" "start + C:/test/test1.txt" "start + C:/test/test2.txt" "start + C:/test/test3.txt" "start + C:/test/test4.txt" "start + C:/test/test5.txt" "start + C:/test/test6.txt" "start + C:/test/test7.txt" "main thread readfiles"
ここから分かることは、、
Thread.new でスレッドを作成して並列処理を行うため、
mainスレッドのpメソッドはイテレーター終了後に実施されるわけではない
→"main thread readfiles_threads"はイテレーターよりも先に表示されている
Thread.valueでスレッド終了後までメソッドがロックできる
→"after"は必ずイテレーター終了後に表示される
並列処理をしていない場合は、
"main thread readfiles"は当然 イテレーターの後に表示される
aliasを使ったよくあるイディオム
メソッドは複数回定義されると上書きされる
def hello p "hello" end def hello p "twice" end hello
■実行結果
"twice"
この性質を利用して、
既存のメソッドに追加するときによくあるイディオム。
def hello p "hello" end alias original_hello hello def hello original_hello p "twice" end hello original_hello
■実行結果
"hello" "twice" "hello"
aliasで既存のメソッドを別名にて退避させておいて、
既存のメソッドを上書く。
なるほど。
あと、returnを明示しなくても複数の返り値を設定する方法があったので、
以前のブログを修正しました