【Ruby】後置ifのメリットって?
こんなコードに対して
リファクタリングをしたのだけど
意図が伝わってないとコメントをもらいました。
後置if は使える 途中にエラーがあってもそれまでの結果を出す方針なら、kaisuはそもそもいらない 最初の一つだけがエラーメッセージをだす条件なら、最初だけを明示的に確認すれば? ループの中でエラーMSGはよくない
やっぱり、
ループの中でエラーMSGはよくない
よね。
もう一度もとのコードから考え直そう。
■元コード
a =(0...10000).to_a p a =( a.sample(4) << -1).sample(5) min = 10000 max = -1 min_doko = 0 max_doko = 0 kaisu = 0 a.each_with_index do |int, i| if int<0 or int>9999 break else if min >int min = int min_doko = i end if max < int max = int max_doko = i end kaisu += 1 end end if kaisu == 0 p "だめな数しか入ってない" exit end p "min" + min.to_s p "max" + max.to_s p "min_doko" + min_doko.to_s p "max_doko" + max_doko.to_s
each_with_index ⇒ while文に変更
i=0 while i < a.size if a[i]<0 or a[i]>9999 break else if min >a[i] min = a[i] min_doko = i end if max < a[i] max = a[i] max_doko = i end kaisu += 1 end i += 1 end
最初の一つだけ明示的に確認
最初の一つだけがエラーメッセージをだす条件なら、最初だけを明示的に確認する。
if a[0]<0 or a[0]>9999 p "ikinari dame na kazu" exit end i=0 while i < a.size if a[i]<0 or a[i]>9999 break else if min >a[i] min = a[i] min_doko = i end if max < a[i] max = a[i] max_doko = i end end i += 1 end
■実行結果
[-1, 102, 3209, 2884, 8250] "ikinari dame na kazu"
確かに。a[0]の値確認だけだから処理も重くないし。
コードもシンプルになった。
後置ifを使う
後置ifはどこに使えるんだろう?
else節がある文は後置に出来ないし↓
a = 1 p "ok" if a == 1 else p a end #syntax error, unexpected keyword_else, expecting end-of-input
ここは例外を使えば一文でかけるので、その結果、後置に出来るけど。
あまりぴんと来ないけどやってみるか
if a[0]<0 or a[0]>9999 p "ikinari dame na kazu" exit end
↓
raise "ikinari dame na kazu" if a[0]<0 or a[0]>9999
■実行結果
in `<main>': ikinari dame na kazu (RuntimeError)
そもそもなぜ、後置ifを使わせたいのか?
処理が早いとか?
def test start_time = Time.now yield (0...10000).to_a end_time = Time.now p ("timeee " + (end_time - start_time).to_s + "s" ) end test do |a| i = 0 while i < a.size if a[i] % 5 == 0 then p i end i += 1 end end test do |a| i = 0 while i < a.size p i if a[i] % 5 == 0 i += 1 end end
■実行結果(略)
"timeee 0.651037s" "timeee 0.631036s"
誤差みたいにみえるけど、何回やっても、
わずかだけ後置ifのほうが処理が早い。
この違いが大事なのかな。。けちんぼ精神?
後置ifの方が処理が早いのは分かったけど、
このコード↓に後置ifが入る余地はないのでは・・?うーん。
■修正後コード全量
a =(0...10000).to_a p a =( a.sample(4) << -1).sample(5) min = 10000 max = -1 min_doko = 0 max_doko = 0 raise "ikinari dame na kazu" if a[0]<0 or a[0]>9999 i=0 while i < a.size if a[i]<0 or a[i]>9999 break else if min >a[i] min = a[i] min_doko = i end if max < a[i] max = a[i] max_doko = i end end i += 1 end p "min " + min.to_s p "max " + max.to_s p "min_doko " + min_doko.to_s p "max_doko " + max_doko.to_s
タイムアップ