Sha256: e43d3008fcee33119aa23b885bb28982693604992d1f1e72abab021157a3b632
Contents?: true
Size: 1.79 KB
Versions: 1
Compression:
Stored size: 1.79 KB
Contents
require_relative 'build' require_relative 'error' require_relative 'failure' require_relative 'success' module Verbalize module Action THROWN_SYMBOL = :verbalize_error def fail!(failure_value = nil) throw(THROWN_SYMBOL, failure_value) end def self.included(target) target.extend ClassMethods end module ClassMethods def input(*required_keywords, optional: []) class_eval Build.call(required_keywords, Array(optional)) end # Because call/call! are defined when Action.input is called, they would # not be defined when there is no input. So we pre-define them here, and # if there is any input, they are overwritten def call __proxied_call end def call! __proxied_call! end private def perform(*args) new(*args).send(:call) end # We used __proxied_call/__proxied_call! for 2 reasons: # 1. The declaration of call/call! needs to be explicit so that tools # like rspec-mocks can verify the actions keywords actually # exist when stubbing # 2. Because #1, meta-programming a simple interface to these proxied # methods is much simpler than meta-programming the full methods def __proxied_call(*args) error = catch(:verbalize_error) do value = perform(*args) return Success.new(value) end Failure.new(error) end def __proxied_call!(*args) perform(*args) rescue UncaughtThrowError => uncaught_throw_error fail_value = uncaught_throw_error.value error = Verbalize::Error.new("Unhandled fail! called with: #{fail_value.inspect}.") error.set_backtrace(uncaught_throw_error.backtrace[2..-1]) raise error end end end end
Version data entries
1 entries across 1 versions & 1 rubygems
Version | Path |
---|---|
verbalize-2.0.1 | lib/verbalize/action.rb |