メソッド
概要
Rubyではすべての操作をメソッドで行います。 ここではメソッドについて説明します。
メソッドとは
Rubyでは全てのデータがオブジェクトでした。 それと同じように、Rubyではすべての操作がメソッドによって行われます。
メソッドはオブジェクトに定義されているもので、そのオブジェクトを操作するために使われます。
例えば、2.4 オブジェクトで出てきた.class
は「オブジェクトのクラスを返す」というメソッドです。
練習問題で出てきた.to_s
は「オブジェクトを文字列オブジェクトに変換する」メソッドです。
メソッドの呼び出し
メソッドを使うことを、「メソッドの呼び出し」といいます。
メソッドは次のようにして呼び出します。
オブジェクト.メソッド名(引数1, 引数2, ..., 引数n)
先頭にオブジェクトがあり、その右に.
(ピリオド、ドット)と呼び出すメソッド名を書きます。
メソッドに別のデータを渡すときは、括弧をつけてカンマ区切りで渡します。
このメソッドに渡すデータのことを引数といいます。
また、メソッドが呼ばれるオブジェクトのことをレシーバとも言います。
例えば演習問題(1)で出てきたFile.read("sample1.txt")
だと、レシーバはFile
、メソッド名はread
、引数は"sample1.txt"
になります。
また、引数の括弧を省略することもできます。次の2つは同じ意味です。
File.read("sample1.txt")
File.read "sample1.txt"
引数がない場合も同様です。
"1234".to_i()
"1234".to_i
レシーバの種類
レシーバには大きく分けて3つあります。
- インスタンス(普通のオブジェクト)
- クラス
- なし
それぞれについて説明します。
インスタンスメソッド
"Hello, world!"
という文字列オブジェクトや、1234
のような数値オブジェクトのような普通のオブジェクトのことをインスタンスといいます。
インスタンスはクラスを元に生成されます。 これまでで説明したオブジェクトという言葉はインスタンスという言葉とほぼ等しいと思ってください。
"Hello, world!"
のようなオブジェクトをインスタンスという言葉を使って正確に説明すると、「"Hello, world!"
はStringクラスのインスタンス」というような言い方になります。
まあ「"Hello, world"
の種類はStringクラス」の言葉を変えただけですね。
インスタンス(オブジェクト)をレシーバにとして呼び出すメソッドのことをインスタンスメソッドといいます。
例えば、次のようなものがあります。
irb(main):001:0> 1234.class
=> Fixnum
irb(main):002:0> 1234.5.to_i
=> 1234
irb(main):003:0> "dog, cat, rabbit".split(",")
=> ["dog", " cat", " rabbit"]
上から
- 整数値オブジェクト(Fixnumインスタンス)がレシーバの
class
メソッド - 小数値オブジェクト(Floatインスタンス)がレシーバの
to_i
メソッド - 文字列オブジェクト(Stringインスタンス)がレシーバの
split
メソッド
となっています。
それぞれのオブジェクトによってどのようなメソッドが使えるかは決まっています。
例えば、Fixnumインスタンスに対してsplit
メソッドは使えません。
irb(main):008:0> 12345.split
NoMethodError: undefined method `split' for 12345:Fixnum
クラスメソッド
インスタンスメソッドの他にクラスをレシーバとするメソッドもあります。 そのようなメソッドをクラスメソッドといいます。
クラスはオブジェクト(インスタンス)の種類のことでした。 そのため、クラスメソッドにはそのクラスのインスタンスを生成するようなメソッドが多いです。
例えば、次のようなものがあります。
irb(main):001:0> String.new("Hello, world!")
=> "Hello, world!"
irb(main):002:0> Time.now
=> 2015-10-14 10:58:27 +0900
irb(main):003:0> File.read("sample1.txt")
=> "# はじめての...(省略)
上から、
String
クラスのnew
メソッドで新しい文字列オブジェクトを生成Time
クラスのnow
メソッドで現在時刻の時刻オブジェクトを生成File
クラスのread
メソッドでファイルの内容から文字列オブジェクトを生成
となっています。
クラスは必ずString
やTime
、File
のように最初が大文字のアルファベットで始まります。
クラスメソッドもクラスによってどのようなメソッドが使えるかは決まっています。
関数的メソッド
Rubyではレシーバを省略できる場合もあります。 そのようなメソッドを関数的メソッドといいます。
例えば、今まで使った中だとputs
やprint
が関数的メソッドになります。
irb(main):001:0> puts "Hello, world!"
Hello, world!
=> nil
このputs
もメソッドで、実はKernel
という特別なクラス1のクラスメソッドになっています。
このようにレシーバを省略するとKernel
クラスのクラスメソッドとして呼び出されます。
なので、puts
は次のように明示的にKernel
クラスのクラスメソッドとして呼び出すこともできます。
irb(main):004:0> Kernel.puts "Hello, world!"
Hello, world!
=> nil
メソッドの定義
メソッドはプログラマが自分で定義することもできます。 メソッドの定義は次のようにします。
def メソッド名(仮引数1, 仮引数2, ..., 仮引数n)
処理
end
仮引数は引数を受取るための変数です。 処理は複数行になっても構いません。
例えば、受け取った引数に対して挨拶するメソッドを作ってみます。
def hello(name)
puts "Hello, " + name
end
# 使うときは普通のメソッドと同じように呼び出す
hello("Ruby")
このプログラムを実行すると、「Hello, Ruby」と表示されます。
メソッドの返り値
メソッドは必ずなにか値(オブジェクト)を返します。 メソッドが返す値を返り値といいます。
返り値はreturn
というキーワードで明示的に指定することができます。
例えば、与えられた数値を2倍した数値を返すメソッドを作ってみます。
def double(number)
doubled = number * 2
return doubled
end
puts double(10)
このプログラムを実行すると、「20」と表示されます。
メソッド内でreturn
を使うと、その後の処理は無視されます。
例えば次のようにしても、puts
は無視されてしまいます。
def double(number)
doubled = number * 2
return doubled
puts "無視されます"
end
また、return
を省略することもできます。
その場合、メソッド内で最後に評価した式の値がメソッドの返り値になります。
def double(number)
number * 2
end
この例だと、メソッド内で最後に評価したのがnumber * 2
なので、引数を2倍した値がdouble
メソッドの返り値になります。
演算子風メソッド
Rubyでは全ての操作がメソッドです。
これまで何度か1 + 2
のように普通の数式っぽい式が出てきましたが、これも実はメソッドを呼び出しています。
こういった演算子風のメソッド呼び出しは、+
や-
のような特別なメソッド名にだけに許可されています。
1 + 2
の場合、1
オブジェクトの+
メソッドを2
を引数として呼び出しています。
なので次の2つは同じ意味になります。
irb(main):001:0> 1 + 2
=> 3
irb(main):002:0> 1.+(2)
=> 3
練習問題
(1) メソッドを使ってみる
irbで今まで使ったメソッドを使ってください。 インスタンスメソッド、クラスメソッド、関数的メソッドをそれぞれ1つずつ以上は使ってください。
(2) 演算子風メソッド
irbで演算子風メソッドを、演算子形式の呼び出しと普通のメソッド形式の呼び出しの両方で実行してください。
最低でも以下の6つはやってみてください。
- 数値 + 数値
- 数値 * 数値
- 数値 - 数値
- 数値 / 数値
- 文字列 + 文字列
- 文字列 * 数値
例 (文字列 + 文字列):
irb(main):002:0> "Hello" + ", world!"
=> "Hello, world!"
irb(main):001:0> "Hello".+(", world!")
=> "Hello, world!"
(3) 挨拶メソッドの定義
以下の処理を行うhello_method.rb
というプログラムを作成してください。
- 受け取った引数に対しての挨拶を画面に出力する
hello
メソッドを定義する hello
メソッドをそれぞれ違う引数で3回以上呼び出す
また、実行して結果が正しいか確認してください。
(4) 2倍メソッドの定義
以下の処理を行うdouble_method.rb
というプログラムを作成してください。
- 受け取った引数を2倍した値を返す
double
メソッドを定義する double
メソッドをそれぞれ違う引数で3回以上呼び出して返り値を画面に表示する
また、実行して結果が正しいか確認してください。
(5) 足し算メソッドの定義
以下の処理を行うsum_method.rb
というプログラムを作成してください。
- 3つの引数を受取り、全てを足した和を返す
sum
メソッドを定義する sum
メソッドをそれぞれ違う引数で3回以上呼び出して返り値を画面に表示する
また、実行して結果が正しいか確認してください。
(6) インスタンスメソッドの定義
特定のオブジェクトに新しくインスタンスメソッドを定義することもできます。 次のようにして定義します。
def オブジェクト.メソッド名(仮引数1, 仮引数2, ..., 仮引数n)
処理
end
例えば、ある文字列オブジェクトに新しくprint_myself
というインスタンスメソッドを定義するには次のようにします。
str = "Hello, world!"
def str.print_myself
puts "私は #{self} です。"
end
str.print_myself
インスタンスメソッドの中では、self
でそのオブジェクト自身を参照することができます。
上記のようなprint_myself
を定義して実行するinstance_method.rb
というプログラムを作成してください。
また、実行して結果が正しいか確認してください。
(7) 自己紹介メソッド
以下の処理を行うintroduce_method.rb
というプログラムを作成してください。
- 名前や年齢などを受け取って自己紹介する
introduce
メソッドを定義する - 自分と隣の人のプロフィールを引数として
introduce
メソッドを呼び出す
また、実行して結果が正しいか確認してください。
1. Kernel
は正確にはクラスではなくモジュールといいます。 ↩