最初の一回だけブロックを実行する

ループを回して最初の一回目だけ処理を行うような場合には、フラグを使って次のようなコードを書くと思います。

first_f = true
ary.each do |elem|
  if first_f
    # do something...
    first_f = false
  end
  # ...
end

これってフラグが表に出ていてあまり美しくないような気がします。クラスにしてフラグを閉じ込めてみたらましになるかなと思って以下のコードを書いてみました。

class OnlyOnceBlock
  def call
    unless defined? @called
      yield
      @called = true
    end
  end
end

使い方はこんな感じ。これも微妙。やっぱりクラスにするのは大袈裟かも。

block = OnlyOnceBlock.new
block.call { puts 'called!!' } # => called!!
block.call { puts 'called!!' } # ブロックは実行されない。