メソッドとは
メソッドとは、簡単に説明すると何らかの処理をひとまとめにして名前を付けたものです。
例えば、「名前を言う」と「趣味を言う」という2つの処理は、図のようにintroduce
という名前を付けて1つにまとめることができます。
他のプログラミング言語では、処理をまとめて名前を付ける機能を「関数」※1 と呼びます。「メソッド」と「関数」は、ほとんど同じ機能ですが、概念が違います。
最初の段階で「オブジェクトは、Rubyで扱うことができる全てのデータ」だと学習しましたが、厳密にはオブジェクトにはデータだけではなく、メソッドも含まれています。
オブジェクトは、「データとそのデータに関連する処理(メソッド)のまとまり」です。
オブジェクト指向言語では、データに関連する処理のことを「関数」ではなく、オブジェクト内のデータを操作するという意味合いが含まれた「メソッド」と呼びます。
うーん。なんだか難しいなぁ。。。
現段階でRubyの全ての仕組みを理解することは難しいので、「メソッドは処理をまとめて名前をつけるもの」とだけ覚えておこう!
メソッドの定義と呼び出し
メソッドの定義について学ぼう
以下のようにメソッドを定義します。
1
2
3
def メソッド名
# メソッドを呼び出した時に実行したい処理
end
キーワードのdef
のあとに「メソッド名」を指定します。
その後のend
までの間に、メソッドを呼び出した時に実行したい処理を指定します。
1
2
3
4
def introduce
p "私の名前は、ぴっかちゃんです。"
p "私の趣味は、サウナです。"
end
動画のようにirbは1行だけではなく、複数行に渡るコードも実行することができます。
1行入力したら「Enterキー」か「returnキー」を押しましょう。
続けて、次の行のコードを入力してください。
最後のend
を入力して「Enterキー」か「returnキー」を押すと、「introduceメソッド」を定義したという=> :introduce
が表示されます。
introduceメソッドを使うには、「メソッドの呼び出し」をする必要があります。
メソッドの呼び出しについて学ぼう
メソッドの呼び出しとは、定義したメソッドを実行させることです。
基本的には、次のような形式でオブジェクトのメソッドを呼び出すことができます。
1
オブジェクト.メソッド名
1
2
"Hello World".length
#=> 11
さきほど定義した「introduceメソッド」は、オブジェクトを省略してメソッド名だけで呼び出すことができます。
1
2
3
4
5
6
def introduce
p "私の名前は、ぴっかちゃんです。"
p "私の趣味は、サウナです。"
end
introduce #メソッド名だけでメソッドを呼び出すことができる
introduce
と打ち込み、メソッドを呼び出してみましょう。「introduceメソッド」はトップレベル(Top Level)という場所で定義したので、メソッド呼び出しの際にオブジェクトを省略することができます。
トップレベルの場所は、以下のように自分で定義するクラスの外側を指します。
※クラスの使い方については、別の章で学びます。
1
2
3
4
5
6
# ここがトップレベル
class
# ここはトップレベルではない
end
# ここがトップレベル
トップレベルにメソッドを定義して呼び出してみよう!
ここからは、Rubyのファイルを使います。
method.rb
という名前のファイルを「pikawakaフォルダ」の直下に作成しましょう。
show_profile
メソッドは、ぴかわかさんのプロフィールを表示するメソッドです。1
2
3
4
def show_profile
p "ニックネーム:ぴかわかさん"
p "趣味:掃除"
end
ファイルを実行しても、動画のようにターミナルには何も出力されません。
「method.rb」にshow_profile
メソッドを定義しましたが、メソッドは定義しただけでは使うことができないと学びましたよね。メソッドを使うには「メソッドの呼び出し」が必要です。トップレベルに定義したメソッドは、メソッド名だけで呼び出すことができます。
1
2
3
4
5
6
def show_profile
p "ニックネーム:ぴかわかさん"
p "趣味:掃除"
end
show_profile
rubyコマンドで「method.rb」を実行すると、上の動画のようにターミナルにぴかわかさんのプロフィールが表示されますね。
ソースコードが読まれる順番を確認しよう
method.rb
のソースコードを確認してみます。
メソッドは、以下のようにメソッドを作る部分である「メソッドの定義」とそのメソッドを実行させる「メソッド呼び出し」に分けることができます。
ソースコードは、以下のように上から順番に読み込まれます。
最初にメソッドの定義部分が読み込まれますが、メソッドは実行されません。
「メソッド呼び出し」が読み込まれたら、show_profileメソッド内の処理が実行されます。
メソッドを定義している部分が読み込まれても、メソッドは実行されないんだね!
メソッドを実行させるのは「メソッド呼び出し」の部分になるよ
メソッドを使うメリットとは
メソッドを使うメリットは、主に以下の通りです。
- 同じコードを何度も書く必要がなくなる
- 保守性が向上する
同じコードを何度も書く必要がなくなる
例えば、以下のように重複しているコードがあるとします。
1
2
3
4
5
6
7
8
p "私の名前は、ぴっかちゃんです。"
p "私の趣味は、サウナです。"
p "私の名前は、ぴっかちゃんです。"
p "私の趣味は、サウナです。"
p "私の名前は、ぴっかちゃんです。"
p "私の趣味は、サウナです。"
同じコードを何度も書くのは、プログラミングする上で非効率になります。さらに長いコードで重複している場合は、読みづらくなります。
メソッドを定義しておけば、処理を書くのは一度だけで済みます。
あとは必要に応じて、メソッドを呼び出すだけです。
1
2
3
4
5
6
7
8
def introduce
p "私の名前は、ぴっかちゃんです。"
p "私の趣味は、サウナです。"
end
introduce
introduce
introduce
他にも処理をまとめているから、コードが読みやすくなるね!
保守性が向上する
メソッドを使うと、あとから修正が発生した場合の対応が簡単になります。
例えば、以下のソースコードで「サウナ」を「ランニング」に修正しなければいけなくなったとします。その際に3箇所の修正が必要です。
1
2
3
4
5
6
7
8
p "私の名前は、ぴっかちゃんです。"
p "私の趣味は、サウナです。" #この行を修正
p "私の名前は、ぴっかちゃんです。"
p "私の趣味は、サウナです。" #この行を修正
p "私の名前は、ぴっかちゃんです。"
p "私の趣味は、サウナです。" #この行を修正
メソッドを使う場合は、以下のように定義部分の1箇所だけの修正で済みます。
1
2
3
4
def introduce
p "私の名前は、ぴっかちゃんです。"
p "私の趣味は、サウナです。" #この行の修正だけで済む
end
例として挙げたサンプルコードは、コード量が少なかったので3箇所をすぐに見つけることができますが、コードの量が増えるほど修正箇所を見つけることは難しくなります。
メソッドを使うことで、保守性を高く保つことができます。
メソッドの戻り値(返り値)
メソッドには、戻り値(または返り値)と呼ばれるものがあります。
初学者の方がメソッドを学習するとき、「戻り値」を理解することが難しいという声も少なくありません。
メソッドの戻り値を理解するには、用語やメソッドの動作の流れをしっかりと押さえておく必要があります。本題の「戻り値とは」へ入る前に、これらを整理していきます。
メソッド呼び出し元・メソッド呼び出し先とは
まずは、用語の確認をしてみましょう。
メソッド呼び出しの部分は「メソッド呼び出し元」、呼び出されたメソッドを定義する部分は「メソッド呼び出し先」と表現されます。
「メソッド呼び出し先」と「メソッド呼び出し元」は、どの部分を指しているのかをしっかり押さえておこう!
メソッドの動作の流れを確認しよう
次にメソッドの動作の流れを確認してみましょう。
以下のサンプルコードで説明します。
ソースコードが読み込まれる順番やメソッドの実行されるタイミングなどは「ソースコードが読まれる順番を確認しよう」で前述しているので省略させて頂きます。
1.先頭行からメソッド呼び出しまでの処理
先頭行から順番に実行を始めて、6行目でshow_profile
メソッドが呼び出されます。
メソッドが呼び出されると、先頭から順番に実行していた処理は一時的に中断されるので、7行目には移りません。処理の位置は、メソッドの先頭に移ります。
2.メソッド本体の処理
続いて、show_profile
メソッドの本体である2行目、3行目が順番に実行されます。このときpメソッドによって、ターミナルに文字列が出力されます。
3.メソッドの最終行から呼び出し元まで
メソッドの最終行である3行目を実行し終えると、以下のように「メソッド呼び出し元」の6行目に処理の位置が戻ります。
処理の位置が「メソッド呼び出し元に戻る」ところがポイント!
4.中断していた処理の続きが開始される
処理の位置が「メソッド呼び出し元」に戻ってきたら、続きが実行されます。
以下のように7行目に移り、8行目が実行されます。
このようにメソッドの動作の流れを確認すると、メソッド呼び出しによって処理の位置が移ることが分かりますね。
まとめ
メソッド呼び出しによって、処理の位置が以下のように移ります。
メソッド本体の実行を終えると、「処理の位置がメソッド呼び出し元に戻る」ことを覚えておこう!
戻り値とは
メソッドの動作の流れでは、メソッド本体の実行が終わると処理の位置が「メソッド呼び出し元」に戻ることを学びましたね。
実はこのとき処理の位置が戻るだけではなく、値も渡しているんです。
以下のように「メソッド呼び出し元」に処理の位置が戻る際には、値が渡されます。この値のことを「戻り値(または返り値)」と呼びます。
Rubyのメソッドは、必ず「戻り値」があります。
それでは、メソッド呼び出し元に対して渡される「戻り値」は、どんな値なのでしょうか。次はRubyにおける戻り値について学んでいきます。
メソッド本体の実行が終わると処理は「メソッド呼び出し元」に戻るだけではなく、何かしらの値を渡しているんだね!
Rubyの戻り値
Rubyでは、定義したメソッドの中で最後に評価された式がメソッドの戻り値になります。
評価とは、式を実行して値を得ることです。
例えば、irbで1 + 1
を実行すると2
という数値が得られます。
つまり「評価された式」とは、式(1 + 1
)を実行して2
を得たことを意味します。
以下のようにshow_profile
メソッドの最終行に1 + 1
を追加した場合は、1 + 1
が最後に評価される式となります。
1
2
3
4
5
def show_profile
p "ニックネーム:ぴかわかさん"
p "趣味:掃除"
1 + 1
end
メソッドの戻り値は、「定義したメソッドの中で最後に評価された式」でしたね。
「評価された式」とは、式(1 + 1
)を実行して2
を得たことなので、「メソッド呼び出し元」に対して渡す戻り値は、数値の2
です。
それでは、元のコードで考えてみましょう。
以下の場合は、最後に評価される式はp "趣味:掃除"
です。
1
2
3
4
def show_profile
p "ニックネーム:ぴかわかさん"
p "趣味:掃除"
end
以下の画像のようにirbでp "趣味:掃除"
を実行すると、文字列である"趣味:掃除"
を得られることがわかりますね。
メソッドの戻り値は「定義したメソッドの中で最後に評価された式」なので、以下の画像のようにshow_profile
メソッドの戻り値は、文字列である"趣味:掃除"
です。
戻り値の活用方法とは
メソッド本体の処理が終わると「メソッド呼び出し元」に処理が戻ること、「戻り値」が渡されることを学びましたが、メソッドの戻り値はどのように活用されるのでしょうか。
戻り値はメソッドの処理結果として、変数に代入して活用されることが多いです。
1
2
3
4
5
6
7
8
9
def add
num1 = 3
num2 = 5
num1 + num2
end
sum = add
p "合計は、#{sum}です。"
6行目のshow_profileメソッドの呼び出しは、コメントアウトしておきましょう。
ターミナルには、"合計は、8です。"
と出力されますね。
「Rubyの戻り値」で学んだように「addメソッド」を呼び出すと、num1 + num2
を実行して得た8
が戻り値として「メソッド呼び出し元」に渡されます。
そして、以下のように「メソッド呼び出し元」のadd
には戻り値が渡されているので、変数sum
には8
が代入されます。
このようにメソッドの戻り値は、変数に代入して活用されます。
return
キーワードのreturn
を使うと、戻り値を指定し、任意の位置でメソッド呼び出し元に処理を戻すことができます。
例えば、以下のsampleメソッドの戻り値は3 + 3
の評価結果である6
となります。
1
2
3
4
5
6
7
8
9
10
def sample
1 + 1
2 + 2
3 + 3 #最後に評価される式
end
return_value = sample # 6が渡される
p "戻り値は、#{return_value}です。"
#=> "戻り値は、6です。"
Rubyでは、定義したメソッドの最後に評価された式が戻り値になるので、上記のような結果となります。
しかし、キーワードのreturn
を使うと、途中で処理をメソッド呼び出し元に戻し、return
で指定した戻り値を渡すことができます。
1
2
3
4
5
6
7
8
9
10
def sample
1 + 1
return 2 + 2 #この行でメソッドの処理を終了させ、4を戻り値として渡す
3 + 3
end
return_value = sample # 4が渡される
p "戻り値は、#{return_value}です。"
#=> "戻り値は、4です。"
上記では、return
で指定した2 + 2
の評価結果である4
が戻り値となります。
メソッドの実行はreturn
の行で終了するので、次の3 + 3
は実行されずに「メソッド呼び出し元」に処理が戻ります。
引数について学ぼう
これまでの学習では、メソッドの本体の処理が終了する際に「メソッド呼び出し元」に対して渡す値である「戻り値」があると学びましたね。
実は最初のメソッド呼び出しの際にも、メソッド本体の処理で利用できる値(あるいは変数)を渡すことができます。この値(変数)のことを引数と呼びます。
「戻り値」はメソッドの実行結果としての値でしたが、「引数」はメソッド本体の処理に利用できる値です。
引数の使い方
引数を使うには、以下のようにメソッド名の後に括弧で引数を囲います。
1
2
3
4
5
def メソッド名(引数)
#処理
end
メソッド名(引数) #メソッド呼び出し
実引数と仮引数
引数には「実引数」と「仮引数」があります。
実引数とは、以下のように「メソッド呼び出しの際にメソッドに引き渡される値(あるいは変数)」のことです。
仮引数とは、以下のように「メソッド呼び出し元から渡される実引数の値を受け取るための変数」のことです。
以下のサンプルコードの「実引数」は5
、「仮引数」は変数のnum
になります。
1
2
3
4
5
6
7
def double(num) # 仮引数は変数num
num * 2
end
sum = double(5) # 実引数は5
p "5の2倍は#{sum}です。"
実引数には、以下のように変数を指定することもできます。
1
2
3
4
5
6
7
8
def double(num)
num * 2
end
num = 5
sum = double(num) #実引数に5が代入された変数numを指定する
p "#{num}の2倍は#{sum}です。"
上記のコードでは、実引数と仮引数が同じ名前(num
)にしていますが、以下のように異なる名前でも問題ありません。
1
2
3
4
5
6
7
8
def double(num) #仮引数はnum
num * 2
end
int = 5
sum = double(int) #実引数はint
p "#{int}の2倍は#{sum}です。"
ただし、メソッド内で引数として渡された値を使うためには、仮引数と同じ名前である必要があるので注意してください。
1
2
3
4
5
6
def double(num)
num * 2 #numでなければ、値を参照できない
end
int = 5
sum = double(int)
こちらの注意点も踏まえて、次に手を動かしながら引数を使ってみます。
引数を使ってみよう
method.rb
では、数値同士を足す「addメソッド」を定義しています。
引数がなくてもメソッドを使うことができていますが、このままでは「addメソッド」は3 + 5
の処理を行うだけのメソッドになります。
1
2
3
4
5
6
7
8
9
def add
num1 = 3
num2 = 5
num1 + num2
end
sum = add
p "合計は、#{sum}です。"
他の数値同士で足したい場合は、新しくメソッドを作らなければいけません。そこで「addメソッド」を再利用するために引数を使います。
1
2
3
4
5
6
7
8
9
def add(num1, num2)
num1 + num2
end
num1 = 3
num2 = 5
sum = add(num1, num2)
p "合計は、#{sum}です。"
引数は、カンマ(,
)で区切ることで複数指定することができます。
上記に書き換えたことで、任意の数値を足すaddメソッドを作ることができました。
"合計は、8です。"
と出力されることを確認しましょう。メソッドの再利用性がもう少し分かるように、irbで試してみましょう。
addメソッドを呼び出す際に渡す値を変えることができるので、再利用性が高まりますね。
変数のスコープ
変数のスコープとは、その変数が使える範囲のことです。メソッド内で定義した変数は、メソッド外で使うことができません。
以下のサンプルコードのようにsampleメソッド内で定義した変数num
は、メソッド外で使おうとするとエラーが発生します。
1
2
3
4
5
6
def sample
num = 1 #メソッド内で定義した変数
end
p num #メソッド外で使えない
#=>NameError (undefined local variable or method `num' for main:Object)
メソッドの内外で値のやり取りを行う場合は、これまで学習してきた「戻り値」や「引数」を利用します。
メソッド内から外側に値を返すのは「戻り値」を利用します。またメソッド外からメソッド内に値を渡すのは「引数」を利用します。
メソッドの命名規則
最後にメソッド名の決まりや慣習を学びましょう。
メソッド名には、英数字やアンダースコア_
、!
や?
を使うことができます。
基本的には、先頭は英小文字で始まります。
1
2
3
4
def introduce
p "私の名前は、ぴっかちゃんです。"
p "私の趣味は、サウナです。"
end
メソッド名を複数単語で表す場合は、変数と同様にスネークケース(単語の間をアンダースコア_
で繋いで書き表したもの)にします。
1
2
3
4
def show_profile
p "ニックネーム:ぴかわかさん"
p "趣味:掃除"
end
メソッド名を動詞の名称にすることで、どんな操作をするメソッドなのか分かりやすくなります。
この記事のまとめ
- メソッドは、何らかの処理をひとまとめにして名前を付けたもの
- メソッドを使うことで「再利用性」や「保守性」が向上する
- メソッドは引数や戻り値を利用することで、メソッドの内外で値をやり取りできる
この記事で学んだことをTwitterに投稿して、アウトプットしよう!
Twitterの投稿画面に遷移します