LoginSignup
2
0

More than 1 year has passed since last update.

配列をネストしたブロックに変換する

Last updated at Posted at 2022-08-19

やりたいこと

配列をネストしたブロックに変換したい。

たとえば、ブロックを受け取る transaction という共通の名前のクラスメソッドを持ったクラス CuteDB, CoolDB, EpicDB があるとして

nested_transactions([CuteDB, CoolDB, EpicDB]) do
  hoge
end

CuteDB.transaction do
  CoolDB.transaction do
    EpicDB.transaction do
      hoge
    end
  end
end

という構造に変換したい。ネストする順番を動的に決定するのが目的。

方法

Proc オブジェクトと Enumerable#inject を利用する。

(@kts_h さんのコメントのおかげで nested_transactions メソッドの実装がシンプルになりました :pray::sparkles:)

module CuteDB
  def self.transaction
    puts('CuteDB start')
    yield
    puts('CuteDB end')
  end
end

module CoolDB
  def self.transaction
    puts('CoolDB start')
    yield
    puts('CoolDB end')
  end
end

module EpicDB
  def self.transaction
    puts('EpicDB start')
    yield
    puts('EpicDB end')
  end
end
    
def nested_transactions(dbs, &block)
  # 配列の最初の要素を一番外側、最後の要素の一番内側にしたいので
  # reverse (reverse_each) する。
  dbs.reverse_each.inject(block) do |nested_blocks, db|
    proc { db.transaction(&nested_blocks) }
  end.call
end

nested_transactions([CuteDB, CoolDB, EpicDB]) do
  puts('I am working on my precious DBs.')
end
# CuteDB start
# CoolDB start
# EpicDB start
# I am working on my precious DBs.
# EpicDB end
# CoolDB end
# CuteDB end

nested_transactions([EpicDB, CuteDB]) do
  puts('I am working on my precious DBs.')
end
# EpicDB start
# CuteDB start
# I am working on my precious DBs.
# CuteDB end
# EpicDB end
2
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0