Open3

rubyのensureを動かして理解する

O.SO.S

raiseする時

エラーがraiseするしないに関わらず実行される。

module EnsureRunner
  def self.run
    puts 11111
    raise 'うおーーー'
    puts 'ensureされなかったよん'
  ensure
    puts 'ensureされちゃった'
  end
end

EnsureRunner.run
11111
ensureされちゃった
test.rb:3:in `test': うおーーー (RuntimeError)
        from test.rb:9:in `<main>'
O.SO.S

エラーがraiseしない時

明示的にraiseしない時でも、ensureは使える。

module EnsureRunner
  def self.run
    puts 11111
  ensure
    puts 'ensureされちゃった'
  end
end

EnsureRunner.run
$ ruby test.rb
11111
ensureされちゃった
O.SO.S

応用例

ログのレベルを一時的に変えて、最後に必ずログレベルを元に戻したい時とかに使える。

class BackfillRunner
  def self.run!
    new.run
  end

  def run
    logging! do
      # ここにバックフィル(埋め戻し)処理をかく。
    end
  end

  private

  def logger = @logger ||= Logger.new($stdout).tap { _1.level = 0 }

  def logging!(&)
    old_logger = ActiveRecord::Base.logger
    ActiveRecord::Base.logger = logger
    yield
  ensure
    ActiveRecord::Base.logger = old_logger
  end
end