2
Help us understand the problem. What are the problem?

posted at

updated at

Ruby はすべてがオブジェクト,は本当?

Ruby は JavaScript などと違い,整数のような基本的な型もオブジェクトとして扱われます。
また,クラスという〈オブジェクトの振る舞いを規定する仕組み〉さえもオブジェクトです。

そのため,初心者向けの記事でよく

Ruby ではすべてがオブジェクトです。

と書かれます。本当でしょうか?
この問いの答えは,「すべて」という言葉の意味によって変わります。

メソッドやブロックはオブジェクトではありません。

「ええ〜? すべてがオブジェクトって嘘だったのかよっ?!」

いえいえ,これは,Ruby のメソッドやブロックはデータとして扱えないというだけです。Python や JavaScript なんかと違うところですね。

「ええ〜? Ruby ショボイじゃん」

いえいえ,そういうわけではありません。メソッドそのもの,ブロックそのものはデータではないのですが,それをデータ化することはでき,それぞれ Method オブジェクト,Proc オブジェクトと呼ばれます。その名のとおり,それぞれ Method クラスと Proc クラスのインスタンスです。当然オブジェクトです。
Method オブジェクト,Proc オブジェクトはデータなので,当然,変数に代入したり,メソッドに実引数として渡したり,そいつが持っているメソッドを呼び出したり,といったことができます。

Proc オブジェクトは,メソッドに実引数として渡せるだけでなく,ブロックとして渡すこともできます。
Method オブジェクトは Proc オブジェクトに変換することもできます。

例を見ましょう。

# 「ブロックパラメーターを 2 乗して返すブロック」を用いて
# 2 乗する Proc オブジェクトを生成
square = proc{ |x| x * x }

# Proc オブジェクトを呼び出す例
p square[3] # => 9

# Proc オブジェクトを map にブロックとして与える例
p (1..3).map(&square) # => [1, 4, 9]
# → 映画「2001 年宇宙の旅」に出てきたモノリスの辺の比率

# 「13 に対する to_s メソッド呼び出し」を表す Method オブジェクトを生成
thirteen_to_str = 13.method(:to_s)

# 引数無しで呼び出すと 10 進で文字列化
p thirteen_to_str[] # => "13"

# 8 進で文字列化
p thirteen_to_str[8] # => "15"

# 2 進,8 進,10 進,16 進で文字列化
# map に & 付きで Method オブジェクトを渡すと,Proc に変換されたうえ,
# ブロックとして渡される。
p [2, 8, 10, 16].map(&thirteen_to_str)
# => ["1101", "15", "13", "d"]

冒頭の問いに戻ります。
「Ruby はすべてがオブジェクト」は,「すべて」の意味合いによっては間違いではないものの,誤解を招きます。
「Ruby はすべてのデータがオブジェクト」と表現すべきでしょう。

Ruby では,変数・定数も演算子も制御構造もデータではないので,オブジェクトではありません。
プログラムもそれ自体はオブジェクトではありません。もちろんプログラムは文字列として表現できるので String オブジェクトで表すことはでき,eval メソッドによって実行することはできます。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
2
Help us understand the problem. What are the problem?