« Project Euler : Problem 40 | トップページ | Project Euler : Problem 41 ~ Pandigital な素数 »

2010年8月 1日 (日)

Ruby の「メソッド」と Python の「関数」の違いは…

 Ruby と Python はどちらも「オブジェクト指向言語」として認識されていると思いますが、違う言語ですから当然文法や言語仕様はそれぞれ独自のものを持っています。そのため、 Python の知識で Ruby を理解しようとすると、ちょっとした誤解を招くことがあります(その逆もまた然り)。

 私がこの記事を書こうと思ったきっかけは、こちらブログでのやりとりでした。
 西尾さんが「引数のない関数呼び出しに括弧がいらない、かつ関数がファーストクラスの言語」の例として Ruby を挙げていらしたので、「それはちょっと違うのでは…」と思い、「ツムジ」の名前でコメントを書いたのですが、どうもうまく誤解を解くことができないようでした。
 以前も同じような記事を書いたことがあったのですが、「同じような勘違いをされている人が結構いるのかも?」と思ったので、自分なりにまとめてみようと思ったのでした。
 私は Ruby との付き合いは結構長いので、 Ruby に関してはある程度知っているつもりです。ところが、 Python に関しては表面をちょっとなぞった程度の知識しかありません。以下の記事の内容で、もし Python に関して間違ったことを書いていた場合は、コメント欄にその旨をご指摘いただけるとありがたいです。

 Python は「オブジェクト指向言語」であると同時に「関数型言語」の要素も持っている(マルチパラダイムってやつですね)ので、「関数オブジェクト」が存在しています。そのため Python では「関数」はファーストクラスになります。
 ところが Ruby はパラダイムとしては「オブジェクト指向」しか持っていません。そのため Ruby には「関数」は存在しません。
 Ruby で Python の「関数」に相当するのは「メソッド」ですが、 言語仕様上 Ruby の「通常のメソッド」はクラス、インスタンス、またはモジュールのいずれかに所属することになっています。そして Ruby における「オブジェクト」は「データ+メソッド」の形をとります。つまり「通常のメソッド」単独では「オブジェクト」として扱われないのでファーストクラスではありません。
 レシーバを指定せずに使える「puts」や「print」などは一見関数のように見えますが、実は「Kernel クラス」のメソッドです。またトップレベルで定義したメソッドもレシーバを指定せずに使えますが、こちらは「Object クラス」のプライベートメソッドとして扱われます。
 西尾さんはこちらブログのコメントに

オブジェクト指向であるかどうかとメソッドや関数がファーストクラスであるかどうかは背反ではなく…
と書いておられますが、「背反する・しない」ではなく Ruby では言語仕様上「通常のメソッド」は単独で「オブジェクト」として扱われないのです。

 また西尾さんは同じくコメントの中で

>> bar = Object.method(:foo) => #<Method: Class(Object)#foo> このメソッドオブジェクトはファーストクラスであるように見えますが、そうではないという主張でしょうか?
と書いておられます。
 これに関しては Ruby マニュアルのclass Methodの項目に
Object#method によりオブジェクト化されたメソッドオブジェクトのクラスです。
と書いてあります。これは「通常のメソッド」が単独では「オブジェクト」になれないので、わざわざ「Object#method」を使って「メソッドをオブジェクト化」するということです。
 ですから、 Ruby に関しては
引数のない関数呼び出しに括弧がいらない、かつ関数がファーストクラスの言語では、逆に「その関数自体」を意味する式をつくるために新しい文法が必要になる。
のではなく、
「メソッド」がもともとファーストクラスではないので、「メソッド」をファーストクラスとして扱うためには「Object#method」や「Method#call」といったものが必要になった。
ということなのです。

« Project Euler : Problem 40 | トップページ | Project Euler : Problem 41 ~ Pandigital な素数 »

Ruby」カテゴリの記事

コメント

コメントを書く

コメントは記事投稿者が公開するまで表示されません。

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/112020/49025324

この記事へのトラックバック一覧です: Ruby の「メソッド」と Python の「関数」の違いは…:

« Project Euler : Problem 40 | トップページ | Project Euler : Problem 41 ~ Pandigital な素数 »

2016年7月
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31            
フォト

最近のトラックバック

無料ブログはココログ