これまで作成したプログラムでは 変数 をたくさん使ってきた。 変数は自分で好きな値を代入すると、それを保持してくれて、あとで 参照したときにその値を返してくれる。
変数が数値、文字列、などのある時点の「値」のみを返してくれるものであ
る一方、メソッド は何かの「手順」を行ない、その結果を返してくれ
る。これまでよく利用してきた printf, gets, to_i
などは
いずれもメソッドである。printf
はフォーマットを決めて
文字列を出力してくれる、gets
は決められた場所
からデータを読んでくれる、
to_i
は元の値を整数に変換してくれる。このような
働きをするのがメソッドである。
メソッドを理解する上で、数学で習った「関数」を思い浮かべると 分かりやすい。
f(x) = 2x + 1
という定義をしておけば、f(4) のように 呼び出すことで、2×4 + 1 を計算したことになる。 ここで、f に与えた 4 のことを引数(ひきすう) という。 関数は、引数に与えられた数値を x に代入して計算を行なう。 メソッドでもこの点は同様である。
メソッドを定義するには def
を利用する。
def メソッド名(引数リスト) 定義本体 end
簡単なメソッドを定義してみよう
def f(x) 2 * x + 1 end
これは、先ほどの f(x) = 2x + 1 と同じ内容なので、 だいたい意味は分かるだろう。
def f(x)
メソッドとして f
という名前のメソッドを定義する。
括弧 ( ) の中に書くのは引数リストという。そして、ここには
x
とだけ書いてある。これは、
メソッド
f
を呼ぶときには引数を1つだけ付けてね
ということを意味している。つまり、別の場所でf
を
呼びたいときには f(5)
のように必ず一つの引数が
必要となる。メソッド定義の引数リストに書く変数は仮引数
といい、メソッドを呼んだときに与えた値が代入される。つまり、
f(5)
と呼んだ場合 x
には5が代入される。
2 * x + 1
def
……end
の間に書くのがメソッドの定義
本体である。ここには、Rubyの文を何でも書くことができる。
ここではたまたま、数学の関数のように数式を書いたが、
printf("2*%d + 1 は %dです\n", x, 2*x+1)
のようにRubyのメソッドを書いても良い。
end
end
でメソッド定義の終了を示す。
この例をファイルに保存しよう。
#!/usr/koeki/bin/ruby # coding: utf-8 def f(x) 2*x + 1 end
実際に実行してみよう。
% chmod +x method-1.rb % ./method-1.rb
なにが起きるだろうか。
メソッドは定義しただけでは動かない。プログラムの別の箇所で 参照しなければなにもせずに終わってしまう。これは数学の答案で 最初の方に
f(x) = 3x + 1 とする
と書いたのに、別のところで f(x) を使わなければ意味がないのと同じである。
メソッドを参照するには、参照したい位置で
と書くだけで良い。たとえば、先ほど定義した f
メソッド
を呼ぶには、
f(3)
のようにすればよい。プログラムを改良してみよう。
#!/usr/koeki/bin/ruby
# coding: utf-8
def f(x)
2*x + 1
end
STDERR.puts "数値を入れて下さい。2倍して1足します。"
y = gets.to_i
printf("%d\n", f(y))
f(y)
の部分が、定義したメソッドの呼び出しであ
る。ここでは、直前の行で読み込んだ数値をy
に
入れていて、それをf
メソッドに渡している。f
メソッドでは、仮引数 x
に入力した値を代入して計算した
結果を返す。
では、次のようなプログラムはどんな結果を返すだろうか。
#!/usr/koeki/bin/ruby
# coding: utf-8
def g(x)
a = x*2
b = 1
c = a + b
end
STDERR.puts "数値を入れて下さい。計算した結果を表示します。"
y = gets.to_i
printf("%d\n", g(y))
今度は g
メソッドに3行の式がある。
a = x*2
b = 1
c = a + b
のどの行が g(x)
の値になるのだろうか? たとえば5を
与えたら
a = 5*2
→ 10
b = 1
→ 1
c = a + b
→11
10か1か11が返ると予想できる。実際に実行してみよう。
% chmod +x method-3.rb % ./method-3.rb 数値を入れて下さい。計算した結果を表示します。 5 11
このように、メソッドでは、そのメソッドを実行するときに 最後に実行した文の値がメソッドの実行結果として返される。 これを返却値という。
また、引数を2つ以上利用するときは
def foo(x, y) x + y*2 end
のように引数リストで仮引数をカンマ(,)で区切って列挙する。この例の場合
呼出し側では2個の値を渡す必要がある。つまりfoo(2, 5)
のよう
に呼ぶ。引数が不要の場合は
def bar() ……なんらかの内容…… end
のように、引数リストの括弧内は空にする。
return
文メソッドの中途で直ちに呼び主に制御を返すこともできる。
def daikei(jotei, katei, takasa) if jotei < 0 || katei < 0 || takasa < 0 # jotei, katei, takasa いずれかが負なら nil を返す return nil end return (jotei+katei)*takasa/2 end
上記の例では、jotei, katei, takasa
いずれかが負の
場合に直ちに nil
を返しメソッドを抜ける。
必ずしも数学の関数のように「結果の値」を返してもらう必要はない。 たとえば、次のようなメソッドも考えられる。
def hello(who) printf("%s さんこんにちは!\n", who) end
このメソッドでは、仮引数として who
をもらい、
それが文字列だとして 「さんこんにちは!」を後置した
メッセージを出力するというだけのものである。実際に利用してみよう。
#!/usr/koeki/bin/ruby # coding: utf-8 def hello(who) printf("%s さんこんにちは!\n", who) end STDERR.puts "あなたの名前を入れて下さい。" you = gets.chomp! hello(you) STDERR.puts "あなたの近くに座っている人の名前を入れて下さい。" friend = gets.chomp! hello(friend)
実際に実行してみよう。
% chmod +x method-4.rb % ./method-4.rb あなたの名前を入れて下さい。 taro taro さんこんにちは! あなたの近くに座っている人の名前を入れて下さい。 hanako hanako さんこんにちは!
メソッドは、決まった式の計算をしてもらうこともできるし、 決まった仕事をしてもらうこともできる。
ちなみに、printf
メソッドも仕事をした結果として
値(nil
)を返している。したがって、hello
メソッドの返却値も nil
となる。ただし、呼出し側の方で、
hello
メソッドの返す値を全く利用していないのでこの値は
捨てられることになる。