array.rb
class NilClass
def [] n
nil
end
end
効果
nil[1] = nil
になります。
irb(main):001:0> [1][2][3]
NoMethodError: undefined method `[]' for nil:NilClass
from (irb):1
from c:/ruby/bin/irb:11:in `<main>'
irb(main):002:0> class NilClass;def [] n;nil;end;end
=> :[]
irb(main):003:0> [1][2][3]
=> nil
irb(main):004:0> [1][2].nil?
=> true
irb(main):005:0> [1][2][3] == nil
=> true
irb(main):006:0> {:a1 =>[1,2,3],:a2=>nil}[:a2][2] == nil
=> true
これによって深い場所の存在確認を一発でできるようになります。
副作用は多分そんなにないはず……
NoMethodError: undefined method `[]' for nil:NilClass
をキャプチャして何かやる人ってちょっと思いつかない。
真面目な人はちゃんと1階層ずつnilじゃない事を確認するはずですし
nil かどうかチェックするならnilと判定されるので
追記:2014/8/21
副作用を思いつきました。このトリックはしばしばデバッグを困難にします。
fault.rb
c
case x
when 1 then
c = x[1][:conf][1]
when 2 then
c = x[2][:cnfo][1] #ここで表記ミス
#以下ちょっと長い処理
end
#ここでなんらかの例外が発生し、cがnilである事に気がつくが
#例外が発生する場所とミスをした場所が離れてて大変な場合もある
以下のようにした方が安全
class NilClass
def [] n
#-vや-W オプションを指定した場合コール元を表示
$stderr.print("#{caller().first} was called NilClass#[]\n") if $VERBOSE
nil
end
end