Skip to content

Instantly share code, notes, and snippets.

@wojtha
Created June 10, 2016 08:33
Show Gist options
  • Select an option

  • Save wojtha/2b7f90a0fcb2f55c70d79532248b585d to your computer and use it in GitHub Desktop.

Select an option

Save wojtha/2b7f90a0fcb2f55c70d79532248b585d to your computer and use it in GitHub Desktop.
FailFast with Wisper events and tweaked block evaluation durring the call - inspired by Rectify::Command.
require 'wisper'
module FailFastWisperRectify
def self.included(base)
base.include Wisper::Publisher
base.include Helpers
base.prepend Proxy
base.extend ClassMethods
end
module ClassMethods
def call(*args, &block)
new.call(*args, &block)
end
end
private_constant :ClassMethods
module Proxy
def call(*, &block)
evaluate_block(&block) if block_given?
catch(:halt) do
super
end
end
def method_missing(method_name, *args, &block)
if @__caller.respond_to?(method_name)
@__caller.send(method_name, *args, &block)
else
super
end
end
def respond_to_missing?(method_name, include_private = false)
@__caller.respond_to?(method_name, include_private)
end
private
# We are evaluating block in the context of the caller. Currently it doesn't
# support callers private methods. Taken from Rectify::Command.
def evaluate_block(&block)
@__caller = eval('self', block.binding)
instance_eval(&block)
end
end
private_constant :Proxy
module Helpers
def rescue_halt
catch(:halt) do
yield
end
end
def halt!
throw :halt
end
def emit(*args)
broadcast(*args)
end
def emit!(*args)
broadcast(*args)
halt!
end
def failure!(*args)
failure(*args)
halt!
end
def failure(*args)
broadcast(:failure, *args)
end
def warning(*args)
broadcast(:warning, *args)
end
def success(*args)
broadcast(:success, *args)
end
end
private_constant :Helpers
end
class SomeOperation
include FailFastWisperRectify
def call(error_level = 0)
failure! "Fatal error!" if error_level > 1
if error_level > 0
failure "Warning!"
emit :custom_warning, "Achtung!"
else
success "hello!"
end
end
end
class ExcitedListenter
def success(*)
puts "OH YEAH!"
end
end
service = lambda do |level|
svc = SomeOperation.new
svc.subscribe(ExcitedListenter.new)
svc.call(level) do
on(:success) { |*args| puts "SUCCESS! #{args.inspect}" }
on(:custom_warning) { |*args| puts "CUSTOM! #{args.inspect}" }
on(:failure) { |*args| puts "FAILURE! #{args.inspect}" }
end
end
puts "(0) ================================="
service.call(0)
# OH YEAH!
# SUCCESS! ["hello!"]
puts "(1) ================================="
service.call(1)
# FAILURE! ["Warning!"]
# CUSTOM! ["Achtung!"]
puts "(2) ================================="
service.call(2)
# FAILURE! ["Fatal error!"]
puts "(3) ================================="
SomeOperation.call(0) do
on(:success) { |*args| puts "SUCCESS! #{args.inspect}" }
end
# SUCCESS! ["hello!"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment