15 December 2011
Rubyのtapはメソッドチェーンだけのものじゃない!
あるインスタンス変数にオブジェクトがセットされているときに、その参照を外しつつ、そのオブジェクトを返すというメソッドが必要になったんだよ。次のような感じだよ。
@name = nil #at initialize
def set_name(name)
@name = name
end
def reset_name
end
set_name('Charlie') # => "Charlie"
reset_name # => "Charlie"
ここでreset_nameしたときに、インスタンス変数にセットされてたオブジェクトを返したいんだ。なんかよくありそうだよね。
こんなときは普通reset_nameを次のように書くと思うんだ。
def reset_name
name = @name
@name = nil
name
end
set_name('Charlie') # => "Charlie"
reset_name # => "Charlie"
でもなんかスマートじゃないよね。
で、少し考えたんだけど、多重代入を使うともう少しマシになるんだ。
def reset_name
name, @name = @name, nil
name
end
set_name('Charlie') # => "Charlie"
reset_name # => "Charlie"
でもやっぱり返り値を確保するためだけにローカル変数を用意しなきゃならないなんて、なんかイケてないよね..
そこでObject#tapの出番ですよ奥さん..
def reset_name
@name.tap { @name = nil }
end
set_name('Charlie') # => "Charlie"
reset_name # => "Charlie"
@name # => nil
tapはそのブロックを評価するけれども、その結果を捨ててしまうという、謙虚な変わり者のメソッドだよ。
なかなかイケてると思うんだけど、どうかな?
周知のTipsだったらごめんね
blog comments powered by Disqus