memo:rubyの「ピュアピュア」を味わう。
http://d.hatena.ne.jp/iox/20070203/1170506166
を自分なりに噛み砕いた。
値渡し/参照渡しってrubyをやると混乱する。
rubyはぴゅあぴゅあなので命名拘束はオブジェクトのポインタ?を格納する
(勉強不足なので断言できませんがおそらく)rubyには参照値を直接操作する方法は用意されていないとおもいます。
結果として仮引数へのバインドは参照値が常に入ります。
ピュアピュアです。キラッ☆って音がしそう。
ちなみにコピーが発生しないので(そこだけは)速度的なアドバンテージ、ってことなのかしら?
#defはクロージャなのか?クロージャっていまいち定義がつかめないので怖い用語使用ですが。。 def test0(hash_in) #devクロージャの始まり。 hash_in = {"a" => 10,"b" => 30} #(1) # {}リテラルによって新しいハッシュオブジェクトが生成され、参照値がhash_inに入る。 #(2)もともとのhash_inに入っていた参照値は上書きされた。 #もともとのhash_inが格納するオブジェクトへのアクセスが #このクロージャからは不可能になった。でもグローバル修飾子とかあるのかも?知らない。 #クロージャの外、プログラム内では #バインドしている変数がある限りGCに片付けられることはないだろう。 #されたらバグってるって。 end #で、defクロージャ終了とともに(1)のハッシュリテラルで生成されたオブジェクトは受け取り手が存在しないなら廃棄されるのだろう(GC的なものが掃除管理する) #なので、オブジェクトをそのまま変更したら当然クロージャー外でもその変化は反映する def test1(hash_in) hash_in["c"] = 3 end def test2(hash_in) hash_in["a"] = 3 end hash_out = {"a" => 1, "b" => 2} test0(hash_out) hash_out # => {"a"=>1, "b"=>2} test1(hash_out) hash_out # => {"a"=>1, "b"=>2, "c"=>3} test2(hash_out) hash_out # => {"a"=>3, "b"=>2, "c"=>3} #ただしrubyは最後の評価がreturnされるのでこのクロージャーの計算結果は #受け取ることは可能。なんとなく漏れ出ているイメージを受ける。 #この仕様は僕は気持ち悪い、と思う。最後の評価がreturnされるって言うのは気持ち悪い。 hash = test0(hash_out) #受け取ってみる hash # => {"a"=>10, "b"=>30} #正直気持ち悪いですね。
以上、「rubyの特徴を味わってみる」
returnしてないのに帰ってくる、というのが気持ち悪くなってきますね。
(2)test0内でのバインドにより格納参照値上書 => 仮引数バインド時のオブジェクトへのアクセス遮断って言う流れがなんともロマンチックです。