Skip to content

Instantly share code, notes, and snippets.

@plexus
Created October 29, 2014 16:00
Show Gist options
  • Save plexus/18d8c96bc52db988f0ad to your computer and use it in GitHub Desktop.
Save plexus/18d8c96bc52db988f0ad to your computer and use it in GitHub Desktop.
module Yaks
# State monad-ish thing.
class StatefulBuilder < BasicObject
def create(*args, &block)
@state = @klass.create(*args)
instance_eval(&block)
@state
end
def initialize(klass, methods)
@klass = klass
StatefulMethods.new(methods).send(:extend_object, self)
end
def validate_state(method_name, args)
unless @state.is_a?(@klass)
::Kernel.raise(
::Yaks::IllegalState,
"#{@klass}##{method_name}(#{args.map(&:inspect).join(', ')}) "\
"returned #{@state.inspect}. Expected instance of #{@klass}"
)
end
end
class StatefulMethods < ::Module
def initialize(methods)
methods.each { |name| define_stateful_method(name) }
end
def define_stateful_method(method_name)
define_method method_name do |*args, &block|
@state = @state.public_send(method_name, *args, &block)
validate_state(method_name, args)
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment