Last active
August 29, 2015 14:10
-
-
Save oozzal/9d8199ad77a01a1a85c5 to your computer and use it in GitHub Desktop.
Java like interface in ruby.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require './engine_interface' | |
class Engine | |
def self.init_with_name name | |
new | |
@name = name | |
end | |
def start | |
puts "Starting" | |
end | |
def stop | |
puts "Stopping" | |
end | |
# must be included at the bottom | |
include EngineInterface | |
end | |
e = Engine.new | |
e.start |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require './interface' | |
module EngineInterface | |
include Interface | |
def self.included klass | |
ensure_instance_methods klass, start: 0, stop: 0 | |
ensure_class_methods klass, init_with_name: 1 | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Interface | |
def self.included klass | |
klass.extend ClassMethods | |
end | |
module ClassMethods | |
def ensure_instance_methods(klass, **methods_hash) | |
ensure_methods(klass.new, methods_hash) | |
end | |
def ensure_class_methods(klass, **methods_hash) | |
ensure_methods(klass, methods_hash) | |
end | |
private | |
# methods_hash sample | |
# {:meth1_name => args_count, :meth2_name => args_count} | |
def ensure_methods(klass, methods_hash) | |
methods_hash.each do |method_name, args_count| | |
if klass.is_a? Class | |
class_name = klass.name | |
method_type = ".#{method_name}" | |
else | |
class_name = klass.class.name | |
method_type = "##{method_name}" | |
end | |
if klass.respond_to? method_name | |
if klass.method(method_name).arity != args_count | |
raise NotImplementedError, "#{class_name}#{method_type} should receive #{args_count} parameter(s)" | |
end | |
else | |
raise NotImplementedError, "Class '#{class_name}' must implement the method '#{method_type}'" | |
end | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment