Skip to content

Instantly share code, notes, and snippets.

@mboeh
Created May 28, 2018 07:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mboeh/6593004b24cba1eabdb33f0c8c3b18f1 to your computer and use it in GitHub Desktop.
Save mboeh/6593004b24cba1eabdb33f0c8c3b18f1 to your computer and use it in GitHub Desktop.
circuit results
class Circuit
class OKResult
def initialize(value)
@value = value
end
def if_break(&blk)
self
end
def if_open(&blk)
self
end
def if_ok(&blk)
OKResult.new(blk.call(@value))
end
def map(&blk)
OKResult.new(blk.call(@value))
end
def value
@value
end
end
class BreakResult
def initialize(error, value = nil)
@error = error
@value = value
end
def if_break(&blk)
BreakResult.new(@error, blk.call(@error))
end
def if_open(&blk)
self
end
def if_ok(&blk)
self
end
def map(&blk)
BreakResult.new(@error, blk.call(@value))
end
def value
@value
end
end
class OpenResult
def initialize(value = nil)
@value = value
end
def if_break(&blk)
self
end
def if_open(&blk)
OpenResult.new(blk.call(@value))
end
def if_ok(&blk)
self
end
def map(&blk)
OpenResult.new(blk.call(@value))
end
def value
@value
end
end
def initialize(open)
@open = open
end
def open?
@open
end
def run(&blk)
if open?
OpenResult.new
else
begin
OKResult.new(blk.call)
rescue => err
BreakResult.new(err)
end
end
end
end
cc = Circuit.new(false)
p cc.run{
"ok"
}.value
p cc.run{
"o"
}.if_ok{|v|
v + "k"
}.value
p cc.run{
raise "not ok"
}.if_ok{
"bad"
}.if_break{|err|
err.message.split(" ").last
}.if_open{
"bad"
}.value
oc = Circuit.new(true)
p oc.run{
"bad"
}.map{|v|
v.nil? ? "ok" : "bad"
}.value
p oc.run{
"b"
}.if_ok{|v|
v + "ad"
}.map{|v|
v.nil? ? "ok" : "bad"
}.value
p oc.run{
raise "not ok"
}.if_ok{
"bad"
}.if_break{|err|
err.message.split(" ").last
}.if_open{
"open"
}.map{|v|
v == "open" ? "ok" : "bad"
}.value
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment