class SafetyDance
Generic 'Result' object for declarative result success/failure/cascade handling.
Usage:
def some_action_that_succeeds(msg); msg; end def some_action_that_fails(msg); raise msg; end SafetyDance.new { some_action_that_succeeds(:success) } #=> SafetyDance SafetyDance.new { some_action_that_succeeds(:success) } .value {|error| "action failed with error #{error}" } #=> :success SafetyDance.new { some_action_that_fails("fail")} .value {|error| "action failed with error #{error}" } #=> "action failed with error 'RuntimeError fail'" SafetyDance.new { some_action_that_succeeds(:success) } .then { some_action_that_succeeds(:another_success } .value {|error| "I am handling #{error}" } # => :another_success SafetyDance.new { some_action_that_fails("fail1") } .then { some_action_that_fails("fail2") } .then { some_action_that_succeeds(:another_success } .then { some_action_that_fails("fail3") } .value {|error| "I am handling #{error}" } # I am handling 'RuntimeError fail1'"
Result object pattern is from johnnunemaker.com/resilience-in-ruby/ e.g. github.com/github/github-ds/blob/fbda5389711edfb4c10b6c6bad19311dfcb1bac1/lib/github/result.rb
Constants
- VERSION
Public Class Methods
error(e)
click to toggle source
# File lib/safety_dance.rb, line 97 def self.error(e) result = allocate result.instance_variable_set(:@error, e) result end
new() { || ... }
click to toggle source
# File lib/safety_dance.rb, line 31 def initialize @value = yield @error = nil rescue => e @error = e end
Public Instance Methods
error()
click to toggle source
# File lib/safety_dance.rb, line 52 def error @error end
ok?()
click to toggle source
# File lib/safety_dance.rb, line 38 def ok? @error.nil? end
rescue() { |error| ... }
click to toggle source
# File lib/safety_dance.rb, line 87 def rescue return self if ok? result = SafetyDance.new { yield(@error) } if result.ok? && result.value! == @error self else result end end
then() { |value| ... }
click to toggle source
# File lib/safety_dance.rb, line 75 def then return self if !ok? SafetyDance.new { yield(@value) } end
then_tap() { |value| ... }
click to toggle source
# File lib/safety_dance.rb, line 80 def then_tap self.then do |value| yield value value end end
to_s()
click to toggle source
# File lib/safety_dance.rb, line 42 def to_s if ok? "#<SafetyDance:0x%x value: %s>" % [object_id, @value.inspect] else "#<SafetyDance:0x%x error: %s>" % [object_id, @error.inspect] end end
Also aliased as: inspect
value() { |error| ... }
click to toggle source
# File lib/safety_dance.rb, line 56 def value unless block_given? fail ArgumentError, "must provide a block to SafetyDance#value to be invoked in case of error" end if ok? @value else yield @error end end
value!()
click to toggle source
# File lib/safety_dance.rb, line 67 def value! if ok? @value else raise @error end end