Tbpgr Blog

Employee Experience Engineer tbpgr(てぃーびー) のブログ

Ruby | Handling Failure | Use bouncer method

概要

Use bouncer method

前提

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

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

詳細

状況

エラーは例外よりもプログラムの状態によって示される。
例えば失敗したシェルコマンドは $? 変数にエラーステータスを設定する。

概要

エラーの状態や例外をチェックするためのメソッドを書いて、例外を上げる

理由

チェック済みメソッドのように、bouncer methods(用心棒メソッド?)は共通ロジックをDRYにして、
主題からずれた低レベルなエラーチェックロジックから高レベルなロジックへと解き放つ。

サンプルコード仕様

シンボリックリンクに関してリンクそのもののモードを一括変更するメソッドを作成します。
内部でFile.lchmodを利用しますが、Windows等ではエラーになるためエラー処理が必要です。
一括変更処理後に、結果配列のサイズをチェックして1件も処理されていない場合はエラーとします。

サンプル1:インラインでエラーチェックのロジックを記述する
サンプル2:bouncer methodを作成する

サンプルコードその1

def lcmod(filename, errior_policy =-> {raise})
  File.open(filename) do |file|
    return yield File.lchmod(filelchown, 0744)
  end
rescue
  errior_policy.call
end


def lchmod_files(files)
  results = []
  Dir.glob(files) do |filename|
    next if FileTest.directory? filename
    lcmod(filename, -> {results << "not implemented lchmod"}) do |ret|
      results << ret
    end
  end
  if results.empty?
    raise ArgumentError, "invalid result"
  end
  results
end

print lchmod_files("*.*"), "\n"
begin
  lchmod_files("hoge.rb")
rescue => e
  puts e
end

出力

["not implemented lchmod", "not implemented lchmod", "not implemented lchmod"]
invalid result

サンプルコードその2

def lcmod(filename, errior_policy =-> {raise})
  File.open(filename) do |file|
    return yield File.lchmod(filelchown, 0744)
  end
rescue
  errior_policy.call
end

def check_lchmod_files_results(results)
  raise ArgumentError, "invalid result" if results.empty?
end

def lchmod_files(files)
  results = []
  Dir.glob(files) do |filename|
    next if FileTest.directory? filename
    lcmod(filename, -> {results << "not implemented lchmod"}) do |ret|
      results << ret
    end
  end
  check_lchmod_files_results(results)
  results
end

print lchmod_files("*.*"), "\n"
begin
  lchmod_files("hoge.rb")
rescue => e
  puts e
end

出力

["not implemented lchmod", "not implemented lchmod", "not implemented lchmod"]
invalid result