せかいや

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

【Ruby】あなたの Ruby コードを添削します 【第 1 回】 pukipa.rb

 
■topic summary
study about this page
 ->Rubyist Magazine - あなたの Ruby コードを添削します 【第 1 回】 pukipa.rb

 
るびまのちょっと前の記事、Rubyコード添削しますを読みました。

るびまリファクタリング記事は、読みやすくて楽しいね。
前にもお勧めした、
せきさん・須藤さんのリファクタ合戦とか。
 
今回はボリュームが多いけど。。
 
 
いつかは私も添削してほしいなー。
やばい!

以下、学んだこと

 

unlessに慣れましょう

あるていど Ruby に慣れれば unless のほうが文を解釈する負担が少なくなると思います。

うーん、、そっかー。
まだ使い慣れないなー。unless, until 。

Exceptionの使いどころ

この例外はプログラムにバグがあることを報告するために投げているわけですから、そう簡単に捕まえられたくはないでしょう

こういうときは、Exceptionを使う。
(クラスを指定しない)rescue で捕獲されることがなくなるから。


 

引数に渡す変数の寿命

寿命も由来も違うわけで、両者を一緒に渡すよう要求してしまうと使いづらくなることうけあいです

newする際に要求するものの寿命を意識する。


 

正規表現の配列もち

re_table = [
  [/^aaa/, 3],
  [/^aa/,  2],
  [/^a/,   1]
]
data = "aab"
p re_table.detect{|re, _| re =~ data }

■実行結果

[/^aa/, 2]

なるほど。Hashよりシンプル。

 

文字列先頭を意味する正規表現

添削の過程で、青木さんは ^ を \A に変更している。
 

^ 行頭にマッチします。行頭とは、文字列の先頭もしくは改行の次を 意味します。
\A 文字列の先頭にマッチします。

http://docs.ruby-lang.org/ja/1.9.3/doc/spec=2fregexp.html

ふむふむ。
 

a = <<EOS
hogehoge
hhh
EOS
p /^hhh/ =~ a
p /\Ahhh/ =~ a
p /^hoge/ =~ a
p /\Ahoge/ =~ a

■実行結果

9
nil
0
0

なるほど。
\Aのほうがキツくなるんだ。


 

when節で代入

case
when htmlchar = $1 then escape(htmlchar)
when bracket  = $2 then a_href($3, bracket, 'outlink')
when pagename = $4 then a_href(page_uri(pagename), pagename, 'pagelink')
when uri      = $5 then a_href(uri, uri, 'outlink')
else

 
とあるところ、

when htmlchar == $1 then escape(htmlchar)

の間違い?と思ったけど違うのね。
代入して、値がnilでなかったらthenを実行、というロジック。
代入だから、この時点で変数(htmlchar)が存在しなくてよい。

こういうイメージ。

case
when a = nil then p "aaa"
when b = ""  then p "bbb"
end

 
■実行結果

"bbb"

なるほど。

 

正規表現インスタンス生成はコストが高い

ruby コマンドに -r profile とオプションを付けてプログラムを実行します。 するとプログラム終了後、標準エラー出力にプロファイルが出力されます

知らなかった。
 

C:\>ruby -r profile test.rb
"bbb"
  %   cumulative   self              self     total
 time   seconds   seconds    calls  ms/call  ms/call  name
  0.00     0.00      0.00        1     0.00     0.00  TracePoint#enable
  0.00     0.00      0.00        2     0.00     0.00  IO#set_encoding
  0.00     0.00      0.00        1     0.00     0.00  Kernel#hash
  0.00     0.00      0.00        1     0.00     0.00  String#inspect
  0.00     0.00      0.00        1     0.00     0.00  Kernel#p
  0.00     0.00      0.00        1     0.00     0.00  TracePoint#disable
  0.00     0.01      0.00        1     0.00    10.00  #toplevel

へー。
 
 

gsubへのブロック渡し

文字列中で pattern にマッチした部分を順番にブロックに渡し、 その実行結果で置き換えます。

http://docs.ruby-lang.org/ja/1.9.2/class/String.html

ふむふむ。

data={
  "aaa" => 3,
  "aa" => 2,
  "a" => 1
}
str = "aaabaabbbabbbaaa"
p str.gsub(/a*/){|s| data[s]}

■実行結果

"3b2bbb1bbb3"

 
なるほど。


 
うわーこの連載、5回も続いてる。。
すごい嬉しいけど、読むのが大変だ!
ちょっと疲れた。。