Array#replace って何が便利なの?
Array#replace は
a = [1, 2, 3] a.replace [4, 5, 6]
とかって使うらしいんだけど
これって
a = [1, 2, 3] a = [4, 5, 6]
ってやっても結果は同じだと思うんだよね。
ベンチマーク取ってみても
require 'benchmark' num = 100000 Benchmark.bmbm(10) do |x| x.report("replace") { num.times do a = [1, 2, 3] a.replace [4, 5, 6] end } x.report("not replace") { num.times do a = [1, 2, 3] a = [4, 5, 6] end } end
Rehearsal ----------------------------------------------- replace 0.359000 0.000000 0.359000 ( 0.375000) not replace 0.281000 0.000000 0.281000 ( 0.297000) -------------------------------------- total: 0.640000sec user system total real replace 0.329000 0.000000 0.329000 ( 0.375000) not replace 0.296000 0.000000 0.296000 ( 0.313000)
replace の方が少し遅いみたいだし。
replace を使うことによるメリットが分からない。
replace って名前のおかげでソースが読みやすくなるとかかな?
いや、別に読みやすくもならないよなぁ…。
追記
コメントで教えて頂いたのだけど
配列を初期化するのと Array#replace では動作が違うみたい。
コメントのコードが分かりやすいのでそのまま使わせてもらいます!
以下がそれ。
def rep1 a a.replace [4, 5, 6] end a = [1, 2, 3] rep1 a p a #=> [4, 5, 6] def rep2 a a = [4, 5, 6] end a = [1, 2, 3] rep2 a p a #=> [1, 2, 3] def rep3 a a[0], a[1], a[2] = [4, 5, 6] end a = [1, 2, 3] rep3 a p a #=> [4, 5, 6]
rep2 のように配列の初期化を使うと意図した通りには動かない。
たぶん rep2 のローカル変数 a に [4, 5, 6] を代入しているので
外の a には影響が出てないんだろうなぁ。
rep2 のローカル変数 a は呼び出し元の a のコピーだもんね。
で、rep3 のように配列の要素を指定すれば
コピー元の a に直接代入してくれる。
だけどそうするなら rep1 のように Array#replace を使った方がスマートに見えます!
基本的なことを全然考えていなかったのだけど
配列の初期化は新しく作った配列の参照を変数に代入してるので
元々の配列と新しい配列は別のオブジェクトになってしまうのだった。
一方 Array#replace は同じオブジェクトの内容を書き換えるメソッド。
だからけっこう違いますね(´▽`;)
a = [1, 2, 3]; a.object_id # => 21624140 a = [4, 5, 6]; a.object_id # => 21623930 別のオブジェクトになってる a.replace [1, 2, 3]; a.object_id # => 21623930 同じオブジェクト