読者です 読者をやめる 読者になる 読者になる

Tbpgr Blog

Ruby プログラマ tbpgr(てぃーびー) のブログ

Ruby | Collecting Inputs | Handle special cases with Guard Clause

概要

Handle special cases with Guard Clause

前提

Confident Rubyではメソッド内の処理を次のように分類しています。
・Collecting Inputs(引数チェック、変換など)
・Performing Work(主処理)
・Delivering Output(戻り値に関わる処理)
・Handling Failure(例外処理)

当記事は上記のうち、Collecting Inputsに関する話です。

詳細

状況

特定の稀なケースにおいて、メソッドの本体はスキップされるべき

概要

早期にメソッドからreturnすることで、影響を及ぼさないようにガード句を利用しなさい。

理由

コーナーケースですぐに・完全に離脱することで、余計な邪魔をされなくなる。

サンプルコード仕様

文字列の大文字小文字を順番に繰り返すstripeメソッドをStringクラスに実装します。
引数upper_startはデフォルトfalseとし、true・falseの設定に応じて大文字から始めるか、
小文字から始めるかを切り替えます。
空文字の場合は特殊ケースとして何も行いません。

サンプルコード(適用前)

空文字のケースをunless文で記述しているため、ネストが深くなり
unless以降の処理時に、読み手の頭の中に
「selfがemptyではないこと」
という条件を記憶していることを強制します。

class String
  def stripe(upper_start = false)
    unless (self.empty?)
      method = upper_start ? :even? : :odd?
      split('').map.with_index do |v, i|
        i.send(method) ? v.upcase : v.downcase
      end.join
    end
  end
end

puts "hogehoge".stripe
puts "hogehoge".stripe true

出力

hOgEhOgE
HoGeHoGe

サンプルコード(適用後)

ガード句を利用して、空文字のケースは即メソッドから離脱しています。

class String
  def stripe(upper_start = false)
    return if self.empty?
    method = upper_start ? :even? : :odd?
    split('').map.with_index do |v, i|
      i.send(method) ? v.upcase : v.downcase
    end.join
  end
end

puts "hogehoge".stripe
puts "hogehoge".stripe true

出力

hOgEhOgE
HoGeHoGe