From: Shin-ichiro Hara Date: 1996-12-27T14:13:27+09:00 Subject: [ruby-list:1537] Re: C++ $B%f!<%6$N$?$a$N 出沢です > そう。悩んだ。 > 「オブジェクトを値渡し」と聞くと(Cみたいな言語での、perlかな) > 「配列を値渡し」と同じように感じて、プロパティも全部copyされて > 渡される様に感じてしまった。 結局「オブジェクトの参照を値渡し」なんですね。 > > ことは出来ない」と言えますが、ruby の様な超高級言語で、物 > > 理的なモデルを援用して解説するのもナンでしょう。 > > 同感なんですが、『C++ユーザのための手引』は > ruby が第二外国語(英語の次)って人向けでなく、CとかC++とかの > 人に向けた C++ユーザのための手引だから 「C++語で説明するなら」 > ということで ポインタ とか使った説明で許されるのでは、、、、 あ、私は生まれてはじめて触る言語が ruby だったら、、、というのを 想定してました。C++語だったら、「Fixnum 以外のクラスが代入された 変数の型は、全てポインタ型である。参照渡しは存在しない。」で決ま りでしょう。 > 私もまず配列ではまりました。 > で次に > def foo(b) > b = "B" もしくは 3 > end > a = "A" もしくは 2 > print a, "\n" # => A もしくは 2 > foo(a) > print a, "\n" # => A もしくは 2 > > あれ? 配列 と 整数や文字列は挙動が違う ってますますはまった。 それ、私も一度実験してみました。(^^; 配列と文字列は違うのかと 思った。正解は「文字列も配列と同じ」。単に配列の方の破壊的操作 (b[0] = "B" など)の方が文字列の方の破壊的操作(b.sub!(/./, "B") など)に比べて馴染みがあっただけ、ということですね。b[0] = "B" は b に対する破壊的操作だが b = "B" は b に対する破壊的操作では ないわけで、上の例でいくと def foo(b) b.sub!(/./, "B") end a = "A" print a, "\n" # => A foo(a) print a, "\n" # => B を考えれば文字列でも配列と同様な事が起こっていることが分かる. > 仮引数に渡されたオブジェクトへの操作により実引数のオブジェクトも操作される > 変数に代入されたオブジェクトへの操作によりもとののオブジェクトも操作される > 仮引数への別のオブジェクトの代入は、実引数に影響しない。 > 変数に別のオブジェクトを代入してもは、もとのオブジェクトには影響しない。 > > んー。事実だけ書いてもなんのこっちゃ? って判ってもらえないだろうな。 > > ここ結構はまるんじゃないかと思う。そうなら 重要だ。 重要だと思います。ここは「破壊的操作」というのをキーワードにまとめ られないかな、と思うのですけど。 > > 結局、オブジェクトとオブジェクトの参照の区別をきちんとつけた > > 上で、 > > んー? > だって 我々が目で見れるのはすべて オブジェクトの参照 でしょ? > ”ABC”とか 2.4 とかの 定数 としての オブジェクト以外は。 そうですね。(ここで「目に見れるのは」とは「変数に格納されるのは」 ということとほぼ同じですよね。)ここでは、オブジェクトの参照とオブ ジェクト本体の差異を概念として区別できなければ、何も説明できないだ ろうという意味で言いました。 もう一つのポイントは print ですね。a の値を知るには print a とすれ ばいいと思いがちですが、ruby では違う。ruby では print a は、a の 属するクラスの to_s メソッドによる結果を出力するだけで、a の値その ものは見ようにも見られない。「参照か値か?」という実験をするのに、 print を使うとしばしば混乱する、ということですね。 さてここで問題です。:-) 次の様に言っても正しいでしょうか? ruby では Fixnum も含めて変数に格納されるのはオブジェクトの 参照である。ただ Fixnum には破壊的操作をするメソッドが用意さ れていないだけである。    Shin-ichro Hara(Nagaoka Univ.of Tech.)