Rubyには値渡ししかない

C++な人は値渡ししかない、と聞くと「え、実引数変更できないの?」なんて思っちゃうけど変更できます。

def bar(baz)
  baz[0] = 5     # 参照先の値を変更
  baz = [2,3,4]  # 参照を変えるだけ
end

quux = [1,2,3]
bar(quux)
print quux       # => 523

C++で値渡しと言うと、以下

void foo(Hoge hoge) { ... }

これだとhogeの実体が全コピーされちゃうなので通常は参照渡し・ポインタ渡しを使う。

void foo(Hoge &hoge) { ... }
//または
void foo(Hoge *hoge) { ... }

「オブジェクト」の違い

渡し方で話をするとわかりづらいが、そもそも「オブジェクト」という言葉が示すものが違う。
C++だとオブジェクトの作り方が下記のように2種類ある。

  Foo foo;
  Foo pfoo = new Foo();

C++では

  • fooをオブジェクト
  • pfooをオブジェクト(へ)のポインタ

というが、
RubyJavaには

  • fooに相当するものがなく
  • pfooに相当するものを「オブジェクト(の参照)」

と言っている。

逆に言えば、C++の場合は「参照」の実現方法がポインタになっていて、その仕組みをプログラマーに見せている、ということ。
そう考えると最初のRubyの関数がこんな風に見えてくる。

def bar(Baz *baz)
  baz->quux = 5;   // (quuxというメンバを持つとして)オブジェクトの値を書き換える
  baz = 0x1234;    // ポインタの値を変えるだけ
end