Rubyのif地獄を卒業!ハッシュディスパッチとポリモーフィズムでコードを劇的に綺麗にする方法
生徒
「Rubyで条件分岐を書いていたら、ifやelsifが20個くらい並んでしまいました。どこに何が書いてあるか分からなくて、読むのが辛いです……。」
先生
「それはプログラマーが恐れる『if地獄』という状態ですね。条件が増えるたびにif文を継ぎ足すと、いずれプログラムが壊れてしまいます。」
生徒
「どうすればスッキリ整理できるんですか?」
先生
「ハッシュディスパッチやポリモーフィズムといった整理術を使いましょう!一見難しそうですが、仕組みがわかればパソコン初心者の方でも魔法のようにコードを短くできますよ。」
1. if地獄とは?多段条件分岐が抱える問題点
プログラミングを始めたばかりの頃は、「もしAならこれ」「もしBならこれ」と一つずつif文やelsifを並べていきます。これを条件分岐と呼びます。
しかし、扱うデータが10種類、20種類と増えていくとどうなるでしょうか。画面がif文で埋め尽くされ、スクロールしないと全体が見えないほど長くなります。これが「if地獄」です。
この状態の問題は、単に見にくいだけではありません。新しく条件を追加したいときに、既存の長いコードのどこに差し込めばいいか迷ったり、誤って別の場所を書き換えてエラーを起こしたりするリスクが非常に高くなります。
日常生活で例えるなら、家の鍵が100本あって、どれがどの部屋の鍵かラベルも貼らずにジャラジャラ持ち歩いているようなものです。目的の鍵を探すだけで一苦労ですよね。これを整理して「辞書」のように管理するのが、今回のテーマです。
Rubyの文法を基礎からしっかり固めたい人や、 現場で役立つ「テスト駆動開発」の考え方まで身につけたい人には、 評価の高いこの一冊がおすすめです。
プロを目指す人のためのRuby入門をAmazonで見る※ Amazon広告リンク
2. ハッシュディスパッチの基本!辞書形式で処理を呼び出す
ハッシュディスパッチとは、Rubyの「ハッシュ」という機能を使って、条件に応じた処理を呼び出すテクニックです。
ハッシュとは、キーワード(鍵)と中身(値)をセットにして保存する入れ物のことです。パソコンでいう「フォルダ分け」や、国語の「辞書」をイメージしてください。
「この言葉が来たら、この動作をする」というルールをあらかじめハッシュに登録しておけば、if文を何度も書かずに、一瞬で目的の処理を取り出すことができます。
3. 実際に比較!if文とハッシュディスパッチの違い
まずは、一般的なif文で書いた場合のコードを見てみましょう。動物の鳴き声を返すプログラムです。
def get_voice_if(animal)
if animal == "いぬ"
"ワンワン"
elsif animal == "ねこ"
"ニャー"
elsif animal == "うし"
"モー"
else
"しーん"
end
end
puts get_voice_if("いぬ")
これをハッシュディスパッチに書き換えると、以下のようになります。
def get_voice_hash(animal)
# 鳴き声辞書を作成
voices = {
"いぬ" => "ワンワン",
"ねこ" => "ニャー",
"うし" => "モー"
}
# 辞書から引いてくる。なければ「しーん」を返す
voices[animal] || "しーん"
end
puts get_voice_hash("ねこ")
コードが非常にスッキリしましたね!動物の種類が100種類に増えても、辞書(ハッシュ)の項目を増やすだけで済み、メインの処理である「引いてくる」部分は一行のまま変わりません。
4. 処理そのものをハッシュに入れる高度な技
ハッシュに入れるのは、単純な文字列だけではありません。「計算する」「画面に表示する」といった「動作(手続き)」そのものを入れることもできます。
Rubyでは、処理の塊をProc(プロック)というオブジェクトにして保存できます。これを使えば、条件ごとに全く違う複雑な計算をさせることも可能です。
# 計算ルールをハッシュに格納
calculators = {
"消費税" => Proc.new { |price| price * 0.1 },
"割引" => Proc.new { |price| price * 0.2 },
"手数料" => Proc.new { |price| 500 }
}
mode = "割引"
price = 1000
# 指定されたモードの計算を実行
result = calculators[mode].call(price)
puts "#{mode}の計算結果は #{result.to_i} 円です"
このように、プログラムの「動き」を部品のようにハッシュへ格納することで、if文での分岐を完全に消し去ることができます。
5. ポリモーフィズムとは?形は違えど使い方は同じ
次にご紹介するのはポリモーフィズム(多態性)です。プログラミングの難しい用語ランキングで常に上位に入りますが、考え方は簡単です。
例えば、「再生ボタン」をイメージしてください。音楽プレーヤーでも、動画サイトでも、DVDデッキでも、「再生ボタンを押す」という操作は同じですよね?中身が何であれ、使う側は「再生」という命令一つだけを知っていれば良い。これがポリモーフィズムです。
Rubyでは、異なる種類のオブジェクト(データの塊)に同じ名前の命令(メソッド)を持たせることで実現します。
6. クラスを使ってif分岐を消滅させる
ポリモーフィズムを使って、「if animal == 'いぬ'」といった判断をプログラムから消してみましょう。
class Dog
def bark
puts "ワンワン!"
end
end
class Cat
def bark
puts "ニャー!"
end
end
# 使う側は、相手が誰でも「bark(鳴け)」と命令するだけ
animals = [Dog.new, Cat.new]
animals.each do |animal|
animal.bark
end
このプログラムには、どこにもif文がありません。それでも、Dogならワンワン、Catならニャーと鳴き分けます。
新しい動物が増えたら、新しいクラス(設計図)を作るだけ。既存のコードを一切いじる必要がないので、安全にプログラムを拡張できるのです。
7. 動的なオブジェクト生成で柔軟性を高める
さらに応用すると、文字列から自動的に適切なクラス(種類)を選び出すこともできます。これを活用すると、ユーザーが入力した内容に合わせて、自動で処理を切り替える賢いシステムが作れます。
例えば、決済手段を選ばせるシステムです。「クレジットカード決済」「コンビニ決済」「銀行振込」など、それぞれ処理は違いますが、最後は「決済実行」という同じボタンで動かしたいですよね。
こうした設計にすることで、開発チームの中で「クレジットカード担当」「銀行担当」と作業を分担しやすくなり、大規模な開発でも混乱が起きにくくなります。
8. どちらを使う?整理術の選び方の基準
ハッシュディスパッチとポリモーフィズム、どちらを使えばいいか迷うかもしれません。初心者のうちは以下の基準で選んでみましょう。
- ハッシュディスパッチ: 処理が短く、データの対応表を作るだけで済む場合。
- ポリモーフィズム: 一つ一つの処理が長く、データごとに独自の持ち物や複雑な動きがある場合。
どちらも「if文を増やさない」という目的は同じです。まずは簡単なハッシュ形式から試してみて、手狭に感じたらクラスを使った設計に挑戦するのが上達の近道です。
9. 脱・初心者!メンテナンスしやすいコードとは
良いプログラムの条件は「今動くこと」だけではありません。「半年後の自分が読んでも理解できること」、そして「誰かが修正しても壊れないこと」が大切です。
if文だらけのコードは、後から来た人にとっては「どこを触ればいいか分からない迷路」です。一方で、整理されたコードは「整理整頓された工具箱」のように、必要な道具をすぐに取り出し、新しい道具を追加する場所もすぐに見つかります。
Rubyという言語は、このような整理整頓を助けてくれる仕組みがたくさん備わっています。最初は少し手間がかかるように感じるかもしれませんが、将来の自分のために、綺麗な設計を心がけてみてください。
10. コンピュータを賢く操るための第一歩
パソコンを触ったことがない方にとって、今日の話は少し背伸びをした内容だったかもしれません。でも、心配しないでください。
プログラミングは「覚え書き」の連続です。最初はif文を書きまくっても構いません。ただ、ふと「これ、もっと綺麗に書けるかも?」と立ち止まったときに、今日のハッシュやクラスの話を思い出してみてください。
一つ一つのif文を削ぎ落としていき、最後に残った洗練されたコードを見たとき、あなたは本当の意味でRubyを自在に操れるプログラマーへと一歩近づいているはずです。焦らず、自分のペースでRubyの楽しさを発見していってくださいね!