Skip to content

Instantly share code, notes, and snippets.

@plexus
Created October 29, 2014 15:48
Show Gist options
  • Save plexus/1f2102a6f5b8e7f4f5f5 to your computer and use it in GitHub Desktop.
Save plexus/1f2102a6f5b8e7f4f5f5 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
class StatefulMethods < ::Module
def initialize(klass, methods)
create_method_delegates(methods)
end
def assert_type(klass, object, method_name, args)
unless object.is_a?(klass)
::Kernel.raise ::Yaks::IllegalState, "#{klass}##{method_name}(#{args.map(&:inspect).join(', ')}) returned #{object.inspect}. Expected instance of #{klass}"
end
end
def create_method_delegates(methods)
module_exec(self, methods) do |this, methods|
methods.each do |method_name|
define_method method_name do |*args, &block|
@state = @state.public_send(method_name, *args, &block)
this.assert_type(@klass, @state, method_name, args)
end
end
end
end
end
def initialize(klass, methods)
@klass = klass
mod = StatefulMethods.new(klass, methods)
mod.__send__(:extend_object, self)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment