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

Tbpgr Blog

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

Ruby | Handling Failure | Use checked methods for risky operations

Confident Ruby Ruby

概要

Use checked methods for risky operations

前提

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

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

詳細

状況

メソッドは、ライブラリやシステムでの失敗可能性のある結果を扱うためにインラインの begin/rescue/end ブロックを含んでいる

概要

失敗可能性のあるシステムやライブラリの呼び出しをメソッドにラップする

理由

一般的な低レベルのエラーをカプセルかすることは、冗長なエラーハンドリングやメソッドの抽象化レベルを保つ助力となる。

サンプルコード仕様

シンボリックリンクに関してリンクそのもののモードを一括変更するメソッドを作成します。
内部でFile.lchmodを利用しますが、Windows等ではエラーになるためエラー処理が必要です。

サンプル1:begin/rescue/endを利用します。
サンプル2:ラッパーを作成する

サンプルコードその1

def lchmod_files
  results = []
  Dir.glob("*.*") do |filename|
    next if FileTest.directory? filename
    File.open(filename) do |file|
      begin
        results << File.lchmod(filelchown, 0744)
      rescue
        results << "not implemented lchmod"
      end
    end
  end
  results
end

print lchmod_files

出力

["not implemented lchmod", "not implemented lchmod", "not implemented lchmod"]

サンプルコードその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 lchmod_files
  results = []
  Dir.glob("*.*") do |filename|
    next if FileTest.directory? filename
    lcmod(filename, -> {results << "not implemented lchmod"}) do |ret|
      results << ret
    end
  end
  results
end

print lchmod_files

出力

["not implemented lchmod", "not implemented lchmod", "not implemented lchmod"]