メソッドを定義する

メソッドとは

これまで作成したプログラムでは 変数 をたくさん使ってきた。 変数は自分で好きな値を代入すると、それを保持してくれて、あとで 参照したときにその値を返してくれる。

変数が数値、文字列、などのある時点の「値」のみを返してくれるものであ る一方、メソッド は何かの「手順」を行ない、その結果を返してくれ る。これまでよく利用してきた 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 と同じ内容なので、 だいたい意味は分かるだろう。

この例をファイルに保存しよう。

method-1.rb

#!/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)

のようにすればよい。プログラムを改良してみよう。

method-2.rb

#!/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 に入力した値を代入して計算した 結果を返す。

では、次のようなプログラムはどんな結果を返すだろうか。

method-3.rb

#!/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行の式がある。

のどの行が g(x) の値になるのだろうか? たとえば5を 与えたら

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 をもらい、 それが文字列だとして 「さんこんにちは!」を後置した メッセージを出力するというだけのものである。実際に利用してみよう。

method-4.rb

#!/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メソッドの返す値を全く利用していないのでこの値は 捨てられることになる。


本日の目次