From: Shin-ichiro Hara Date: 1996-12-27T04:27:01+09:00 Subject: [ruby-list:1533] Re: C++ $B%f!<%6$N$?$a$N まつもと ゆきひろです > rubyには値渡ししかなく引き数として与えられた変 > 数の値を変えても元の式の値は変わりません.ただし,オブジェク > トの参照が渡るので値に対して破壊的な操作は可能です. この言葉は全く正しいのですが(作者の言葉なんだから当たり前 だ^^;)、ちょっと読むと、前半で「値渡ししかなく」と言いなが ら後半「参照が渡る」と反対の事を言っている様にみえて、かな り難しいですね。 私は今はもう馴れてしまったけど、perl から移って来たとき一番 難しいのはこの「値渡しか参照渡しか?」という問題だと思います。 FAQ を作るとしたら、このあたりをうまく説明したいと思っている のですが。 最初にハマッタのは、 a = b = [] a.push "A" b.push "B" で a も b も ["A", "B"] になることですね。これではなかなか安 心して仕事が出来ないと思って、しばらく変数は dup しまくって代 入してました。:-) > rubyには値渡ししかなく引き数として与えられた変 > 数の値を変えても元の式の値は変わりません. と、ここだけ読むと def foo(b) b[0] = "B" end a = ["A"] print a, "\n" # => A foo(a) print a, "\n" # => B となるのと矛盾するように見えますよね。a の値が変わらないと いうのなら、その値とは何?という事になりますよね。このあた りのうまい解説方法はないでしょうか? C 言語だったら、「C 言語では f(a)という形式の関数呼び出しで a のアドレスを渡す ことは出来ない」と言えますが、ruby の様な超高級言語で、物 理的なモデルを援用して解説するのもナンでしょう。 「破壊的な操作」の定義も難しいですよね。私も最初は何が破壊 的で何が破壊的でないのか区別がつきにくかった。 例えば上の foo(a) は、配列 a に対して破壊的な作用をしてい るのですが、b[0] = "B" は破壊的な操作ではないですよね。し いていえば、 a[0] = "B" は、a にとっては破壊的な操作であるが、a[0] にと っては破壊的でない。 というところでしょうか。ここももっとうまい解説がほしい。 > Arrayに限らず全ての代入は参照の代入であり,オブジェクトの状 > 態を変更するとみんな変わります. これも誤解して読むと a = "A"; b = a; a = "B" としても b は "A" のままなのは何故か?ということになる。もちろんその答え は a = "B" はオブジェクト "A" の状態ではなく a の値を変更 しているだけだから、となるわけですが。 結局、オブジェクトとオブジェクトの参照の区別をきちんとつけた 上で、 (1)Fixnum 以外のクラスのオブジェクトを変数に代入するとき、 代入されるのは、その参照である。 (2)オブジェクトの参照でなくオブジェクトそのものを変更する ことを破壊的な操作と呼ぶ という感じで説明するしかないのでしょうかね。難しいなあ。習う より馴れろ、とか言いたくないなあ。(^^;