Skip to content

Instantly share code, notes, and snippets.

@sergueif
Last active August 29, 2015 13:55
Show Gist options
  • Save sergueif/8762754 to your computer and use it in GitHub Desktop.
Save sergueif/8762754 to your computer and use it in GitHub Desktop.
module Ext
class Protocol
def initialize(meths, dispatch={})
@dispatch = dispatch
@meths = meths
end
def adapt(obj)
w = obj.class.ancestors.detect do |klass|
@dispatch[klass]
end
adapter = @dispatch[w]
adapted = adapter.new(obj)
#silly-ish I know:
unless (@meths - (adapted.methods - Object.new.methods)).empty?
raise "Adapter #{adapter} doesn't implement full protocol interface, #{@meths.inspect}"
end
adapted
end
def extend(dispatch)
Protocol.new(@meths, @dispatch.merge(dispatch))
end
end
EachProtocol = Protocol.new([:each])
end
module MyAppOrLib
class StringEach
def initialize(str)
@str = str
end
def each(&block)
@str.each_char(&block)
end
end
EachProtocol = Ext::EachProtocol.extend({
String => StringEach
})
class Doer
def do
EachProtocol.adapt("abc").each do |part|
puts part
end
end
end
end
MyAppOrLib::Doer.new.do
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment