Rubyがミニツク

あなたのRubyの技術に関するより詳しい知識と理解を増やします。

Ruby入門コース

このコースについて

Rubyのeラーニング研修システムはRailsを使ってWebアプリケーション開発ができる技術者の育成を目指します。 そのため、Railsを扱うことができるだけのRubyの知識を得ることがRuby入門コースの目標となっています。

コンテンツ一覧

ヒント レッスンの名前をクリックすると、その内容を表示します。

次のコンテンツ ホームへ戻る

ポリモルフィズム

オブジェクトにメッセージを送ることによって、そのメッセージに対する手続きがあればオブジェクトはメッセージに対する処理を実行します。このメッセージに対する手続きは、違うオブジェクトに対して同じようなメッセージを送っても似たような動きをしてくれるかもしれません。そのようなことをポリモルフィズムと呼びます。

p "abc".length      #=> 3
p [1, 2, 3].length  #=> 3
p {:foo => 1, :bar => 2, :baz => 3}.length  #=> 3

異なるオブジェクトごとにlengthメソッドを使っても、それぞれのオブジェクトにとって"length"というメッセージに対して妥当である値が返っています。

ダックタイピング

ダックタイピング(Duck Typing)とは「アヒルのように歩き、アヒルのように鳴くものはアヒルに違いない」という格言からきた言葉です。この言葉は、「オブジェクトを特徴付けるのは実際の種類ではなく、そのオブジェクトがどのように振る舞うか」という意味です。これはオブジェクトがどのようなクラスに属しているかで考えるのではなく、そのオブジェクトがどのようなメソッドを知っているかで考えることです。

def print_length(obj)
  puts("obj length is #{obj.length}")
end

メソッドの引数へ渡されるオブジェクトがlengthメソッドを知っていれば処理は実行されます。どのようなオブジェクトであっても同じ動作をするならば、異なるオブジェクトであっても気になりません。または異なるオブジェクトであっても、操作できるものが同じであれば処理を共通化できます。このような考え方のことをダックタイピングと呼びます。

アイデンティティ

異なる変数が指し示すオブジェクトはどのくらい同じなのでしょうか。あるオブジェクトの値と別のオブジェクトの値が同じなのかは演算子で判定することができます。メソッドは各オブジェクトごとに、適切に定義されなければいけません。なぜなら各オブジェクトごとに何を比べて同じと判定するかは違うからです。

a = "foo"
b = a
# 同じ文字かで判定する
p(a == b)  #=> true
c = [1, 2]
d = c
# 配列の要素が同じかで判定する
p(c == d)  #=> true
e = 1
f = "1"
# 異なるオブジェクトで判定する
p(e == f)  #=> false

このようなオブジェクトを比較する時に使うメソッドについて説明します。

object_idメソッド

各オブジェクトごとに持っている一意な整数を返します。オブジェクトに対してどのような整数が割り当てられるかは不定です。

a = "foo"
b = "bar"
# どのような整数が割り当てられているかはわからない
p(a.object_id)
p(b.object_id)

eql?メソッド

eql?メソッドでふたつのオブジェクトを比較すると、オブジェクトの値が同じならtrueを返します。オブジェクトの値が違う時はfalseを返します。

a = "foo"
b = "foo"
p(a.eql?(b))  #=> true
a = "foo"
b = "bar"
p(a.eql?(b))  #=> false

equal?メソッド

equal?メソッドでふたつのオブジェクトを比較すると、オブジェクトが同じならtrueを返します。オブジェクトが違う時はfalseを返します。

a = "foo"
b = "bar"
p(a.equal?(b))  #=> false
a = "foo"
a = b
p(a.equal?(b))  #=> true

これらのオブジェクトを判定するメソッドには違いがあります。オブジェクトの値が同じであってもオブジェクトそのものが同じであるかはわかりません。ふたつのオブジェクトが同一であるかを判定するにはequal?というメソッドを使います。equal?メソッドはそれぞれのオブジェクトが持つ固有の値であるIDを比較して判定します。このIDはobject_idメソッドで調べることができます

a = "foo"
b = "foo"
p(a == b)       #=> 値が同じなのでtrue
p(a.equal?(b))  #=> 値が違うのでfalse
a = b
p(a.equal?(b))  #=> 同一なのでtrue


次のコンテンツ ホームへ戻る