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をオブジェクト(へ)のポインタ
- fooに相当するものがなく
- pfooに相当するものを「オブジェクト(の参照)」
と言っている。
逆に言えば、C++の場合は「参照」の実現方法がポインタになっていて、その仕組みをプログラマーに見せている、ということ。
そう考えると最初のRubyの関数がこんな風に見えてくる。
def bar(Baz *baz) baz->quux = 5; // (quuxというメンバを持つとして)オブジェクトの値を書き換える baz = 0x1234; // ポインタの値を変えるだけ end