07 March 2014
DRY重患者RubyistのためのNullObjectパターン
以前私はRubyistはDRY症候群に掛かっているという記事を書いた。
要約するとDRYじゃないコードを見るとRubyistはムズムズするといった内容だ。
前回私が書いた記事の中に、次のようなコードが出てきた。
def run
@methods.inject(@obj) do |mem, method|
if custom = Filter.filters[method]
custom.call(mem)
else
mem.send method
end
end
end
これは@methods
に格納したメソッドを@obj
に対し順次呼び出すが、同名のフィルタがFilter.filtersにあるのならそれをcallする、といったコードである。
あなたが重度のDRY症候群に掛かっているなら、このコードを見てムズムズしているに違いない。
これは一般に、「あるなら呼べ、そうでないならお前は黙ってろ」パターンと呼ばれている。以下も同様である。
user.age if user
liz.score && liz.score[:math]
しかし、この頻出するパターンに対し患者たちは叫ぶ。「そうじゃない。僕たちはこう書きたいんだ。」
def run
@methods.inject(@obj) do |mem, method|
Filter.filters[method].call(mem) || mem.send(method)
end
end
user.age
liz.score[:math]
これを、「呼んで駄目なら黙ってろ」パターンという。
当然、Rubyからは次のような返事が帰ってくる。
filter.rb:34:in `block in run': undefined method `call' for nil:NilClass (NoMethodError)
重患者のための即効性特効薬
そこで私は彼ら重度患者のために、21年の歳月を掛けてこの深刻なる問題について研究を重ねた。そして遂にその特効薬を開発したのだ。その名も「NullObjectモジュール」。
module NullObject
refine NilClass do
def method_missing(m,*a,&b)
self
end
end
end
患者たちは直ちにusing
を使ってあなたの体にNullObjectを注入せよ。
早期の回復を望んでいる。
私も一つ打っておくか…。
using NullObject
User = Struct.new(:name, :age, :scores)
charlie = User.new('Charlie', 12)
charlie.scores = { math:35, english:78, music:60 }
charlie.scores[:math] # => 35
liz = User.new('Liz', 17)
liz.scores[:math] # => nil
ほんとうにヤバい人は、naught
を使ってくださいm(__)m
関連記事:
blog comments powered by Disqus