give IT a try

プログラミング、リモートワーク、田舎暮らし、音楽、etc.

【プログラミング初心者向け】メソッドや関数を定義するときの考え方

はじめに:どうやってメソッドを定義したらいいの?

僕がメンターをやっているフィヨルドブートキャンプで、生徒さんから「自分でどうやってメソッドを定義すればいいのかわからない」という質問がありました。 質問をくれた生徒さんいわく、「メソッドを定義するのにあたって手が止まってしまうのは、メソッドを前提にプログラムを考えて書いていないからなのでしょうか」とのことです。

僕の場合、プログラムを作るときは「メソッド(または関数)を作ることを前提に」とは考えていません。ただ、わかりやすいプログラムを書くためには自然とメソッドの定義が必須となってくるので、あたかも息をするようにメソッドを定義している、という感じです。

とはいえ、それだと何の答えにもならないと思うので、「こんなふうに考えてみるのはいかが?」というたとえ話(?)を考えてみました。

メソッドを定義するときの考え方

メソッド定義は処理をグループ分けしてプログラムの見通しをよくする作業、と考えてみるといいかもしれません。

たとえば、以下のようなプログラム(作業手順)があったとします。 ですが、このままだとダラダラと作業が羅列されているだけなので読むのがしんどいです。

スーパーに行く
肉を買う
玉ねぎを買う
カレールーを買う
ご飯を炊く
玉ねぎを切る
玉ねぎを炒める
肉を炒める
水を入れる
ルーを入れる
しばらく煮込む
皿にご飯を盛り付ける
カレーをご飯の上にかける
カレーを食べる
皿や鍋を洗う

そこで見出しを付けて作業をグルーピングすることにします。 こうすると「ここからここまでは何の作業なのか」がわかりやすくなります。

# 食材の購入
スーパーに行く
肉を買う
玉ねぎを買う
カレールーを買う

# 調理
ご飯を炊く
玉ねぎを切る
玉ねぎを炒める
肉を炒める
水を入れる
ルーを入れる
しばらく煮込む

# 食べる
皿にご飯を盛り付ける
カレーをご飯の上にかける
カレーを食べる

# 片付け
皿や鍋を洗う

さらに、上のグルーピングをメソッドとして定義し、それを順番に呼び出すことにします。 そうすると最初に目に入るのは「食材の購入→調理→食べる→片付け」の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】フィヨルドブートキャンプでメンターやってます

冒頭に書いたとおり、僕はフィヨルドブートキャンプというプログラミングスクールでメンターをやっています。 完全未経験の人でもプログラミングを学べるので、興味がある人はぜひ覗いてみてください〜。

bootcamp.fjord.jp