我通过编写一个简单的DSL来学习ruby。 DSL用于支持事件源块。
class Coupon
include AggregateRoot
attr_reader :status
on :CouponApprovedEvent do |event|
#want to update @status of Coupon instance
#but the binding is with Coupon class
@status = 'APPROVED'
end
#other instance methods of Coupon
end
" on"优惠券映射的方法阻止给定事件,该事件用于重构聚合。它在模块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 do
@event_handlers = {}
def self.on event_clazz, &operation
@event_handlers[event_clazz] = operation
end
def self.event_handlers
@event_handlers
end
end
end
end
但由于该块与优惠券类绑定,因此以下测试失败,因此它更新Coupon class.status而不是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
所以我改变了这样的块调用来移动绑定:
module AggregateRoot
def handle event
operation = self.class.event_handlers[event.class.name.to_sym]
instance_eval(&operation)
end
end
在这种情况下,测试通过,但我找到了| event |参数丢失(优惠券实例被传递)。
有没有办法用args移动块的绑定?
答案 0 :(得分:1)
尝试使用以下代码而不是operation.call event
:
instance_exec(event, &operation)