はじめに:どうやってメソッドを定義したらいいの?
僕がメンターをやっているフィヨルドブートキャンプで、生徒さんから「自分でどうやってメソッドを定義すればいいのかわからない」という質問がありました。 質問をくれた生徒さんいわく、「メソッドを定義するのにあたって手が止まってしまうのは、メソッドを前提にプログラムを考えて書いていないからなのでしょうか」とのことです。
僕の場合、プログラムを作るときは「メソッド(または関数)を作ることを前提に」とは考えていません。ただ、わかりやすいプログラムを書くためには自然とメソッドの定義が必須となってくるので、あたかも息をするようにメソッドを定義している、という感じです。
とはいえ、それだと何の答えにもならないと思うので、「こんなふうに考えてみるのはいかが?」というたとえ話(?)を考えてみました。
メソッドを定義するときの考え方
メソッド定義は処理をグループ分けしてプログラムの見通しをよくする作業、と考えてみるといいかもしれません。
たとえば、以下のようなプログラム(作業手順)があったとします。 ですが、このままだとダラダラと作業が羅列されているだけなので読むのがしんどいです。
スーパーに行く 肉を買う 玉ねぎを買う カレールーを買う ご飯を炊く 玉ねぎを切る 玉ねぎを炒める 肉を炒める 水を入れる ルーを入れる しばらく煮込む 皿にご飯を盛り付ける カレーをご飯の上にかける カレーを食べる 皿や鍋を洗う
そこで見出しを付けて作業をグルーピングすることにします。 こうすると「ここからここまでは何の作業なのか」がわかりやすくなります。
# 食材の購入 スーパーに行く 肉を買う 玉ねぎを買う カレールーを買う # 調理 ご飯を炊く 玉ねぎを切る 玉ねぎを炒める 肉を炒める 水を入れる ルーを入れる しばらく煮込む # 食べる 皿にご飯を盛り付ける カレーをご飯の上にかける カレーを食べる # 片付け 皿や鍋を洗う
さらに、上のグルーピングをメソッドとして定義し、それを順番に呼び出すことにします。 そうすると最初に目に入るのは「食材の購入→調理→食べる→片付け」の4ステップだけになります。
食材の購入() 調理() 食べる() 片付け() def 食材の購入 スーパーに行く 肉を買う 玉ねぎを買う end def 調理 ご飯を炊く 玉ねぎを切る 玉ねぎを炒める 肉を炒める 水を入れる ルーを入れる しばらく煮込む end def 食べる 皿にご飯を盛り付ける カレーをご飯の上にかける カレーを食べる end def 片付け 皿や鍋を洗う end
上のコードでは実際に実行される作業は最初のバージョンと同じですが、ご覧のとおり、最初のダラダラしたプログラムとは異なり、メソッドを定義することでプログラムの見通しをよくすることができました。
他にも重複したコードをなくすためにメソッドを定義する(同じコードを何度も書く代わりに、メソッドを繰り返し呼び出す)、という考え方もあるのですが、大きなプログラムではどうしてもコードが長くなってくると思うので、まずはこの「処理のグルーピング」というアプローチでメソッド定義を考えてみるといいんじゃないかと思います。
さらに:引数と戻り値も活用する
上の説明では状況をシンプルにするためにあえて省いていましたが、実際にコードを書くと、メソッドの引数や戻り値も必要になってくるはずです。
イメージ的にはこんな感じですね。
食材 = 食材の購入() カレー, 調理器具 = 調理(食材) 食器類 = 食べる(カレー) 片付け(食器類, 調理器具)
さらにさらに:重複をなくすためにメソッドを定義する
グルーピングのためのメソッド定義だけでなく、コードの重複をなくすためのメソッド定義もできるようになっておきましょう。
先ほど示した例では
def 片付け 皿や鍋を洗う end
となっていましたが、ここではこの「片付け」メソッドが次のように実装されていたとします。
def 片付け スポンジに洗剤を付ける 皿の汚れを水で軽く流す 皿をスポンジでこする 皿に付いている泡を水で流す きれいな布巾で皿の水気を取る スポンジに洗剤を付ける 鍋の汚れを水で軽く流す 鍋をスポンジでこする 鍋に付いている泡を水で流す きれいな布巾で鍋の水気を取る end
上のメソッドを良く見ると、洗い物をする手順はほぼ同じ(つまり重複している)で、異なるのは皿と鍋の部分だけです。
こういう場合は重複を無くすためのメソッド定義が有効です。皿や鍋を「何か」という引数に置き換えてあげると、次のような「洗う」メソッドが定義できます。
def 洗う(何か) スポンジに洗剤を付ける 何かの汚れを水で軽く流す 何かをスポンジでこする 何かに付いている泡を水で流す きれいな布巾で何かの水気を取る end
そして、こうすれば「片付け」メソッドから作業の重複を無くせます。
def 片付け 洗う(皿) 洗う(鍋) end def 洗う(何か) スポンジに洗剤を付ける 何かの汚れを水で軽く流す 何かをスポンジでこする 何かに付いている泡を水で流す きれいな布巾で何かの水気を取る end
豆知識:重複をなくす=DRYにする
ちなみに、重複をなくすことをプログラマの業界では「DRYにする」と言います。 DRYは"Don't repeat yourself"の略語です。
Don't repeat yourself - Wikipedia
先輩プログラマはおそらく頻繁に「ここのコードがDRYじゃないね」とか「もっとDRYにしよう」みたいなことを言ってくると思います。そのときは頭の中で次のように翻訳してください。
- ここのコードがDRYじゃないね = コードの重複が発生してるね
- もっとDRYにしよう = コードの重複をなくそう
この用語は「達人プログラマー」という本の中で提唱されたプログラミングの基本原則です。
まとめ
というわけで、今回のエントリではプログラミング初心者向けにメソッドや関数を定義するときの考え方を説明してみました。 自分でメソッドや関数を定義するのが苦手、という人の参考になれば幸いです😃
【PR】フィヨルドブートキャンプでメンターやってます
冒頭に書いたとおり、僕はフィヨルドブートキャンプというプログラミングスクールでメンターをやっています。 完全未経験の人でもプログラミングを学べるので、興味がある人はぜひ覗いてみてください〜。