Skip to content

Instantly share code, notes, and snippets.

@geeksam
Created October 11, 2012 21:02
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save geeksam/3875462 to your computer and use it in GitHub Desktop.
Save geeksam/3875462 to your computer and use it in GitHub Desktop.
Roles in Ruby
class Role < Module
IncompleteInterface = Class.new(RuntimeError)
def included(receiver)
missing_methods = @public_api.map(&:to_sym) - receiver.public_instance_methods.map(&:to_sym)
unless missing_methods.empty?
raise IncompleteInterface,
"#{receiver} must implement these methods: #{missing_methods.inspect}"
end
# other plumbing...
end
def public_api(*methods)
@public_api = methods.flatten
end
end
StickyNotePlacer = Role.new do
public_api :place_sticky_note
end
class Thingy
def place_sticky_note
"yup"
end
include StickyNotePlacer
end
puts Thingy.new.place_sticky_note
class OtherThingy
include StickyNotePlacer # => raises Role::IncompleteInterface
end
@marnen
Copy link

marnen commented Dec 20, 2012

I like this a lot. I may have to try it.

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