バリケンのRuby日記 RSSフィード

2006-05-23

[] 図解「String#<<」メソッドの動作  図解「String#<<」メソッドの動作 - バリケンのRuby日記 を含むブックマーク はてなブックマーク -  図解「String#<<」メソッドの動作 - バリケンのRuby日記  図解「String#<<」メソッドの動作 - バリケンのRuby日記 のブックマークコメント

今日こちらのお題に図解で答えてみるよ!

>> a = 'aaa'
=> "aaa"
>> b = a
=> "aaa"
>> a = a << 'bbb'
=> "aaabbb"
>> b
=> "aaabbb"

じゃあ、最初の行から。

irb(main):001:0> a = 'aaa'
=> "aaa"

次のようなイメージになるよ。

f:id:muscovyduck:20060522092412p:image

次の行は、

irb(main):002:0> b = a
=> "aaa"

こんなイメージだね。

f:id:muscovyduck:20060522092408p:image

さて、問題の次の行。

irb(main):003:0> a = a << 'bbb'
=> "aaabbb"

ここは、「String#<<」メソッドの動作を理解する必要があるよ。このあいだの「String#+」メソッドは破壊的じゃなかったけど、こんどの「String#<<」メソッドは「破壊的メソッド」なんだ。

まず「a = a << 'bbb'」というのは「a = a.<<('bbb')」と書いたのと同じなんだよ。つまり、

  1. Stringクラスオブジェクトである"aaa"に対して、
  2. "bbb"というリテラル引数として、
  3. 「<<」というメソッドを実行すると、
  4. その結果オブジェクト破壊された(つまり"aaabbb"に変化した!)

という動作になるよ。だから、結果のイメージは次のとおりだね。

f:id:muscovyduck:20060523094010p:image

だから、次のような結果になるんだよ。

irb(main):004:0> b
=> "aaabbb"

昨日の「String#+」メソッドと比べてみてね。もっと詳しく知りたい人は、「Rubyレシピブック 268の技」の「レシピ60 文字列の末尾に文字列を追加する」で詳しい挙動が解説されているよ。

[] Object#object_idメソッド  Object#object_idメソッド - バリケンのRuby日記 を含むブックマーク はてなブックマーク -  Object#object_idメソッド - バリケンのRuby日記  Object#object_idメソッド - バリケンのRuby日記 のブックマークコメント

Rubyでは、オブジェクトが生成されると、それぞれのオブジェクトに対して固有のIDが振られるよ。

そして、オブジェクトに対してObject#object_idメソッドを使うと、そのIDを知ることができるよ。

これを利用すると、「String#+」メソッド「String#<<」メソッドの挙動の理解を深めることができるよ。


まずは「String#<<」メソッドだよ。

a = 'aaa'
a.object_id
b = a
b.object_id    #=> a.object_idと同じになる
a = a << 'bbb' #=> ちなみに a << 'bbb' とも書ける
a.object_id    #=> さっきと同じ
b.object_id    #=> やっぱり同じ
puts a
puts b

次に「String#+」メソッドだよ。

a = 'aaa'
a.object_id
b = a
b.object_id    #=> a.object_idと同じになる
a = a + 'bbb'  #=> ちなみに a += 'bbb' とも書ける
a.object_id    #=> 変わっている!
b.object_id    #=> こっちは変わっていない
puts a
puts b

図解と比較してみてね。

secondlifesecondlife2006/05/23 09:55わかりやすい図付き解説ですばらしいですね!

muscovyduckmuscovyduck2006/05/23 10:05secondlifeさん>
ありがとうございます!

トラックバック - http://rubyist.g.hatena.ne.jp/muscovyduck/20060523