ARGVはfrozen,代入してもfrozen.dupで複製

コマンドラインから引数を受取る配列ARGVは変更が禁止(凍結)されている.例えば,コマンドラインから受取った文字列に別の文字列を連結しようとするSam.rbを実行するとエラー(can't modify frozen string (TypeError))となる.

Sam.rb:

#! /usr/bin/ruby

s='foo' #これは動く
p s<<'bar'

p ARGV[0]<<'bar' #これはエラー

実行結果:

$ Sam.rb 'foo'
"foobar"
/Sam.rb:7:in `<<': can't modify frozen string (TypeError)
       from ./Sam.rb:7

ARGVを別変数に代入しても凍結になったままである.

Sam.rb:

#! /usr/bin/ruby

s='foo' #これは動く
p s<<'bar'

a=ARGV[0]  #ARGV[0]を変数aに代入.
p a<<'bar' #エラー

実行結果:

$ Sam.rb 'foo'
"foobar"
./Sam.rb:7:in `<<': can't modify frozen string (TypeError)
        from ./Sam.rb:7

凍結す外すにはdupメソッドで値を複製する.

Sam.rb:

#! /usr/bin/ruby

s='foo' #これは動く
p s<<'bar'

b=ARGV[0].dup #dupメソッドで複製
p b<<'bar' #これも動く

実行結果:

$ Sam.rb 'foo'
"foobar"
"foobar"

cloneメソッドを使うとfreezeも一緒にコピーするのでエラーとなる.

Sam.rb:

#! /usr/bin/ruby

s='foo' #これは動く
p s<<'bar'

b=ARGV[0].clone #cloneメソッドで複製
p b<<'bar' #これはエラー

実行結果:

$ Sam.rb 'foo'
"foobar"
./Sam.rb:7:in `<<': can't modify frozen string (TypeError)
        from ./Sam.rb:7