ruby - shift the binding of block with args -
i'm learning ruby writing simple dsl. dsl used support event sourcing block.
class coupon include aggregateroot attr_reader :status on :couponapprovedevent |event| #want update @status of coupon instance #but binding coupon class @status = 'approved' end #other instance methods of coupon end
the "on" methods of coupon maps block given event, used reconstitute aggregate. defined in module aggregateroot:
module aggregateroot attr_reader :events def handle event operation = self.class.event_handlers[event.class.name.to_sym] operation.call event end def self.included(clazz) clazz.class_eval @event_handlers = {} def self.on event_clazz, &operation @event_handlers[event_clazz] = operation end def self.event_handlers @event_handlers end end end end
but following test fails due block binded coupon class, therefore updates coupon class.status instead of coupon instance.status.
class coupontest < minitest::unit::testcase def setup @id = 1 @ar = coupon.new(@id) end def test_reconsititute_aggregate_root @ar.handle(couponapprovedevent.new(@id)) assert @ar.approved? end end
so changed block call shift binding:
module aggregateroot def handle event operation = self.class.event_handlers[event.class.name.to_sym] instance_eval(&operation) end end
the test passes in case, found |event| argument lost(the coupon instance passed instead).
is there way shift binding of block args?
try using code below instead of operation.call event
:
instance_exec(event, &operation)
Comments
Post a Comment