答になってなかった。あーつまりだな

def do2 a; a = a + [2,3]; end

これの左辺の a は「新しい」 a で、誰からも参照されてないんだよ。
do2 では 引数の a は変化してない。

def do1 a
p a.object_id
a.concat [2,3]
p a.object_id
end

def do2 a
p a.object_id
a = a + [2,3]
p a.object_id
end

a1 = a2 = [1,2]
do1(a1)
p a1.object_id
p a1
do2(a2)
p a2.object_id
p a2


これに書き直して動かしてみな。do2の最後で表示する5つ目のIDだけが違うはずだから。