Skip to content

Instantly share code, notes, and snippets.

@shreve
Created March 5, 2018 16:52
Show Gist options
  • Save shreve/ba96ac250b73f797a3c253a8cbed7b62 to your computer and use it in GitHub Desktop.
Save shreve/ba96ac250b73f797a3c253a8cbed7b62 to your computer and use it in GitHub Desktop.
Respondable DSL Ideas
#
# Response Handler DSL Demo
#
# The goal of this update is twofold:
# 1. Make the code read more clearly about what it's doing
# 2. Remove the need for the understands? method to be written
#
#
# More Readable Code
#
# Currently, we trim the response body down to a single character and
# compare it against string literals containing characters. This is a
# pretty explicit way to handle things, but doesn't translate well
# what kinds of responses we're looking for.
#
# This new DSL seeks to improve this by using named matchers backed by
# regular expressions. This eliminates the need for two different versions
# of the body: raw, and compressed.
#
#
# Automatic Understands
#
# This new format leads to a world where the response handler can be
# aware of all it's possible code paths. The handler simply needs to
# evaluate the handle_response block, and it will generate a list of
# the matchers it can use. As seen in the demo below, this list will
# be responsive to the respondable's state.
#
# This means the understands? method can be generic to fit all
# respondable use cases. It simply needs to traverse the list of
# used matchers and see if the body fits any.
class ResponseHandler < Respondable::ResponseHandler
response_matcher positive: /^[yY]/,
negative: /^[nN]/
handle_response do |reply|
# If a reply block matches and returns a string, execution will stop
reply.quit do
stop_wizard!
t('message.quit')
end
# Examples of using matchers
reply.any_of(:yes, :no) { } # yes and no are predefined matchers
reply.positive { } # positive and negative are defined
reply.negative { } # in this file
reply.match(/^[yYnN]/) { } # one-off regex
reply.is("goodbye") { } # exact match
reply.any { } # will always match
# Depending on state, you can assign different branches as well
if asked_delivery_method
handle_delivery_method(reply)
else
set_delivery_address(reply)
end
end
def handle_delivery_method(reply)
reply.is("A") do
delivery_method = "SMS"
end.is("B") do
delivery_method = "Email"
end.is("C") do
delivery_method = "Mail"
end
end
def set_delivery_address(reply)
reply.any { delivery_address = response.body }
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment