Skip to content

Instantly share code, notes, and snippets.

@CrowdHailer
Created August 15, 2015 12:17
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save CrowdHailer/a7db54594af431f2f617 to your computer and use it in GitHub Desktop.
Save CrowdHailer/a7db54594af431f2f617 to your computer and use it in GitHub Desktop.
Enforcing an interface in Ruby
class CreatePost
# An interactor to create a post.
# Initialize with a request object that implements the request interface for this interactor.
def initialize(request)
RequestInterface.required_on! request
@user = {:title => request.title}
end
def result
@user
end
end
module Interface
# General basis for an interface
NotImplemented = Class.new ArgumentError
# Indicates a target object does not implement the checked interface
MissingMethod = Class.new ArgumentError
# Raised when a method from the interface is not supported by the implementation
InvalidReturn = Class.new ArgumentError
# Raised when the target return value does not meet the expectaions on it.
# Check if an interface is implemented on a target
# Checked by seeing if the interface module is fronting the ancesor chain
def implemented_on?(target)
target.class.ancestors.first == self
end
# Enforce a target implements the interface
def required_on!(target)
raise NotImplemented unless self.implemented_on? target
end
end
# successul usecase
request = CreatePost::RubyRequest.new 'Building a ruby interface'
puts CreatePost.new request
# failed usecase
begin
request = CreatePost::RubyRequest.new 5
CreatePost.new request
rescue ArgumentError => err
puts err
end
class CreatePost
module RequestInterface
# Interface specification for request objects that are used to initialize the create_post interactor
# build on the general interface
extend Interface
# any request object must have a title method and it must return an instance of String
def title
if defined?(super)
value = super
raise Interface::InvalidReturn unless value.is_a? String
value
else
raise Interface::MissingMethod
end
end
end
end
class CreatePost
class RubyRequest
# A simpe implementation of the request interface for a create post interactor
# The request interface fronts this implementation.
prepend RequestInterface
def initialize(title)
@title = title
end
def title
@title
end
end
end
@magynhard
Copy link

In the meantime there is a ruby gem class_interface to use the interface pattern in ruby easily:
https://github.com/magynhard/class_interface

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment