表題の通り、メソッド内で仮引数に対し破壊的な操作を行なってはならいという話です。
細かい説明は省いて、以下に具体的な (ただしあまり現実的ではない) コードを示します。
def strip_and_add_star(a)
a.strip!
"#{a}☆"
end
str = " ねむい "
new_str = strip_and_add_star(str)
p new_str #=> "ねむい☆"
p str #=> "ねむい" # OPS!
メソッド strip_and_add_star
内で仮引数 a
に対して String#strip!
という破壊的操作を行なったことで、実引数である str
の内容も変更されてしまいました。恐いですね。
たとえば、Rails プロジェクトで some_method(options = {})
というメソッド中があったとして、その中で options
に初期値を設定しようと options.reverse_merge!(:foo => :bar)
と書かかれているケースをたまに見かけますが、これはメソッド呼び出し元の options
の中身を書き換えていて危険です。
一見冗長に見えても options = options.reverse_merge(:foo => :bar)
と書きましょう。