青山です。

On Sun, 31 Oct 1999 23:56:38 +0900,
nosuzuki / e-mail.ne.jp (Norio Suzuki) wrote:

> となっています。この文章と違っていますよね。それともこれは、同じく 
> Ruby 本 P.44 の脚注 *15
> 
> ! Ruby の多くのメソッドは必要に応じて自動的にオブジェクトのコピーを作っ
> ! てくれますから...
> 
> に当てはまっているのでしょうか?

おしい(?)です。ちょうど後で第2弾としてこの部分を書こうと思っていたの
ですが、先の alias に似た概念というだけでは、まだ不十分なんですよね。

もう1つ、変数はオブジェクトでは無い、"foo" 等は新たなオブジェクトを生
成するという事を認識する必要があります。

On Sun, 31 Oct 1999 21:49:40 +0900,
nosuzuki / e-mail.ne.jp (Norio Suzuki) wrote:
> foo = "foo"
> bar = foo
> foo = "bar"

これは、

foo = String.new("foo")
bar = foo
foo = String.new("bar")

と同じで、2つのオブジェクトが生成されます。そして、= はコピーではなく、
別名付けに近く、コピーは行われません。

そして、この別名付けというのは、オブジェクトに対してであり、変数に対し
てではありません。つまり、bar = foo の段階で bar が指し示すのは foo と
いう変数ではなく、foo が指し示しているオブジェクト "foo" です。

したがって、foo --> "bar", bar --> "foo" となります。

先のように alias と書いてしまうと、メソッド名の alias と混乱する可能性
があるので、あまり安易にはあの例は書かない方が良いという面もあるのです
が、あえて再び alias で説明してみると、こんな感じです。

alias String.new("foo") foo
# オブジェクト "foo" を生成し、それに foo というタグを付ける

alias foo bar
# foo というタグの付いたオブジェクトに、bar というタグを付ける

alias String.new("bar") foo
# オブジェクト "bar" を生成し、それに foo というタグを付ける

重要な点は、「変数はオブジェクトでは無い」「主役はオブジェクトであり、
変数では無い」といった感じでしょうか。

これらは、メソッドへのオブジェクトの引き渡し等の理解にも有効かと思います。

def foo(n)
  n.reverse!
end
a = [1,2,3,4,5]
foo(a)
p a  # [5, 4, 3, 2, 1]

このような場合、Ruby における引数の受渡しは参照渡しであるという説明が
一般的ですが、参照渡しに馴染みが無い方などには、変数はオブジェクトでは
無い、Ruby における主役はあくまでオブジェクトであり、引き渡されるのは、
変数が指し示すオブジェクトである。という説明で、どうでしょうかね。

foo(a)  # 引き渡すのはオブジェクト。a(変数)はオブジェクトではない。
        # 従って(?)、引き渡されるのは、a が指し示す [1,2,3,4,5]

もう一工夫という感じですが、わりといい線のような気もします。

> # "=" もメソッド?

いえ、代入は新たに別なオブジェクトにタグを付けるわけですから、その段階
ではまだオブジェクトとの関連は無く、メソッド呼び出しも出来ませんよね。
従って、メソッドではなく、Ruby 自身が処理する演算子です。


-- 
青山 和光 Wakou Aoyama <wakou / fsinet.or.jp