Rubyist Magazine 出張版 を読んだ


なんというか、自分のような Ruby 初学者にとっては、
とてつもなく面白かった。Ruby だけにとどまらず、プログラムとか、
OOP とかそういう話は勉強になったし、あと文章自体もすごい楽しい。
ただ忘れてしまいそうなので気になったところをメモしておく。


とりあえずまず気になったところとして・・・、


・rdefs コマンドは便利そう。
・クラスによる分岐は避ける。
・module_eval はまだちゃんとよく分かってない><
・indent とか config の書き方とか、漠然と気になっていたところが丁寧に書いてあってよかった。
Rspec も使ってみよう。


unless と until を使う

while !@ scanner.eos?
#↓
while not @scanner.eos?
#↓
until @scanner.eos?
if pagelist.size > 0
#↓
if not pagelist.empty?
#↓
unless pagelist.empty?



ではなぜ if not よりも unless が、while not よりも until がよいのでしょうか?
その理由は、文を構成する要素数が減るからです。わたしが「 if not A 」という式を見る場合、
まず if を見て、A を見て、それを not で反転します。つまり脳内操作は3つです。しかし
「 unless A 」の場合、unless を見て、A を見れば終わりなので 2つです。


Ruby の protected と C++/Java の protected を混同しない



private と protected の違いはみなさんご存知でしょうか?
どちらを指定しても基本的にはオブジェクトの外からは呼べなくなるのですが、
protected のメソッドは、同じクラスか、そのサブクラスのインスタンスに限っては
外からでも呼ぶことができます。


http://saikyoline.jp/weblog/2007/11/09/164933.html
http://www.pistolfly.jp/weblog/2008/03/rubyprivateprotected.html


正規表現マジックナンバーではない



なお、セミナーの当日に会場で「一回しか使われていないからといってリテラルを埋め込んでしまったらマジックナンバーのようにならないか」という質問がありました。わたしの答えはこうです。「正規表現マジックナンバーではない」。マジックナンバーとは、それ自体では意味をなさない、本質的には他の何であっても構わない数値のことです。しかし正規表現はそれ自体で十分に意味が限定されますから、マジックナンバーと同列に考えるべきではありません。
とは言えもちろん、正規表現が非常に複雑なときにはすぐに意味がとれませんから、名前を付ける価値はあります。しかしそれはマジックナンバーというより、複雑な手続きを関数としてくくりだす操作にたとえられるべきです。一つの正規表現が複数回使われる場合も同様です。
また、マジックナンバーマジックナンバーでなくするためには適切な名前を付ける必要があります。ひるがえって「regex」「regex2」という変数名はどうでしょうか。これでは型以外の情報をすべて捨ててしまっており、むしろ情報量が低下しています。せっかく名前を付けるのなら、例えば dl_marker_re と dl_body_re のような名前にすべきでしょう。


例外クラスの定義は1行で書く

class NoMemberError < StandardError; end


引数について問い合わせるメソッドを作らない


size_of(name)・・・・・name メンバのバイト長を返す
data_of(name)・・・・・name メンバの値を返す
write_to(name, val)・・name メンバに値 val を代入する



一般的に、「xxxx_of」「xxxx_to」のように前置詞で終わるメソッドが並んでいたら何か間違っているのではないかと疑ってみるべきです。
なぜなら、そういうメソッドは引数に関する値を返していいるからです。つまり自分に関係のないオブジェクトについて値を返す責任を負っています。
このメソッド郡は例えば次のように変形すべきです。


fetch(name).size
fetch(name).value
fetch(name).value = val


正規表現コンパイルの最適化



このコードでは正規表現リテラルに式を埋め込んでいますが、
その式がすべて定数です。つまりメソッド呼び出しごとに値が変わったりすることはありません。
そのような場合は正規表現リテラルに o オプションをつけて処理を高速化できます。

正規表現の o オプションには「その正規表現を最初の1回だけコンパイルする(2回目からは1回目の結果を利用する)」
という働きがあります。



HikiDoc では正規表現リテラルに o オプションをつけたほうがいいという話をしましたが、
今度は逆の例を示します。

MSGID = /<[^\@>]+\a[^>\@]+>/o



この場合、そもそも式の埋め込みがないので、o オプションをつける意味がありません。
正規表現リテラルに o オプションをつけるべき場面は、次の条件がすべて満たされている場合です。

1, 式の埋め込みを使っている。
2, 埋め込む値がプロセスの実行中に変化しない。
3, そのリテラルから何度も正規表現が生成される。