Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class Op
- class FailedOp < StandardError;end
- attr_accessor :params, :context
- def initialize(params,context={})
- @params = params
- @context = context
- context[:success] ||= true
- end
- def self.steps(&block)
- define_method :run, block
- end
- def self.call(params, context={})
- op = self.new(params, context)
- op.run
- op
- end
- def fail!(message)
- raise FailedOp.new(message)
- end
- def failed?
- !success?
- end
- def success?
- context[:success]
- end
- def step(name_or_op=nil, &block)
- run_step(name_or_op, &block) unless failed?
- end
- def failure(name_or_op=nil, &block)
- run_step(name_or_op, &block) unless success?
- end
- def run_step(name_or_op, &block)
- if block_given?
- yield
- else
- case name_or_op
- when NilClass
- raise ArgumentError.new("step should have a name, proc or Op class if no block is given.")
- when String, Symbol
- method(name_or_op).call
- else
- name_or_op.call(params, context)
- end
- end
- rescue FailedOp => e
- context[:error] = e
- context[:success] = false
- context.freeze
- end
- end
- class Op1 < Op
- steps do
- step :one
- step :two
- step Op2
- step do
- step :four
- failure :five_fail
- end
- failure :ensure_bla
- end
- def one
- puts "one #{params}"
- end
- def two
- puts "two #{params}"
- end
- def four
- puts "four #{params}"
- end
- def five_fail
- puts "five_fail #{context}"
- end
- def ensure_bla
- puts "ensure_bla #{context}"
- end
- end
- class Op2 < Op
- steps do
- step :three
- end
- def three
- fail!("Error")
- end
- end
- o = Op1.call({a: 1})
- # one {:a=>1}
- # two {:a=>1}
- # ensure_bla {:success=>false, :error=>#<Op::FailedOp: Error>}
- # => #<Op1:0x00007fda018180e8 @params={:a=>1}, @context={:success=>false, :error=>#<Op::FailedOp: Error>}>
- o.context
- #=> {:success=>false, :error=>#<Op::FailedOp: Error>}
- o.params
- #=> {:a=>1}
- o.failed?
- #=> true
- o.success?
- #=> false
Add Comment
Please, Sign In to add comment