Skip to content

Instantly share code, notes, and snippets.

@yggie
Last active August 29, 2015 14:18
Show Gist options
  • Save yggie/096bf0a799deba41c5fe to your computer and use it in GitHub Desktop.
Save yggie/096bf0a799deba41c5fe to your computer and use it in GitHub Desktop.
Experimenting with Ports
class Port
attr_accessor :output_port
def initialize(inner_port = nil)
inner_port.output_port = self if inner_port
@inner_port = inner_port
end
def perform(*args)
@inner_port.perform(*args)
end
def success!(*args)
@output_port.success!(*args)
raise Done
end
def fail!(*args)
@output_port.fail!(*args)
raise Done
end
def execute(*args, &block)
original_output_port = @output_port
@output_port = Output.new(block)
perform(*args)
rescue Done
# do nothing
ensure
@output_port = original_output_port
end
class Done < Exception; end
class Output
def initialize(block)
block.call(self)
end
def success!(*args)
@success_block.call(*args)
raise Done
end
def fail!(*args)
@failure_block.call(*args)
raise Done
end
def success(&block)
@success_block = block
end
def failure(&block)
@failure_block = block
end
end
end
class Interactor < Port
def perform(a_symbol)
fail! unless a_symbol.is_a? Symbol
success!(a_symbol.to_s.length)
success!('oh dears')
end
end
class Gateway < Port
def perform(*args)
new_args = args.map(&:to_sym)
super(*new_args)
end
def success!(*args)
super(*args.map { |a| a*100 })
end
end
Gateway.new(Interactor.new).execute('some argument') do |result|
result.success do |res|
puts 'HURRAY', res
end
result.failure do
raise 'Oh noes'
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment