rubyaasm

Yield items in AASM after callback


Can you yield items inside an :after callback? I got LocalJumpException when I execute the code below

require 'aasm'
class TestClass
  include AASM
  aasm do
    state :created, initial: true
    state :running
    event :run do
      transitions from: :created,
      to: :running,
      after: proc { yield 1 }
    end
  end
end
TestClass.new.run! { |v| puts v }

Solution

  • It is impossible out of the box since aasm discards code blocks passed to event invocations, but hey, it’s ruby.

    require 'aasm'
    class TestClass
      include AASM
      aasm do
        state :created, initial: true
        state :running
        event :run do
          transitions from: :created,
          to: :running,
          after: -> { @λ_run.call(1) if @λ_run } # invoke the code block if was passed
        end
      end
    end
    TestClass.prepend(Module.new do
      def run!(*args, &λ)
        @λ_run = λ # store the code block passed to the method
        super
      end
    end)
    TestClass.new.run! { |v| puts v.inspect }
    

    With a bit of meta-programming it should be easy to extend to all the defined event handlers.