class TableSync::Utils::InterfaceChecker
Ruby does not support interfaces, and there is no way to implement them. Interfaces check a methods of a class after the initialization of the class is complete. But in Ruby, the initialization of a class cannot be completed. In execution time we can open any class and add some methods (monkey patching). Ruby has `define_method`, singleton methods, etc.
Duck typing is a necessary measure, the only one available in the Ruby architecture.
Interfaces can be implemented in particular cases with tests for example. But this is not suitable for gems that are used by third-party code.
So, we still want to check interfaces and have a nice error messages, even if it will be duck typing.
Next code do this.
Constants
- INTERFACES
Attributes
object[R]
Public Class Methods
new(object)
click to toggle source
# File lib/table_sync/utils/interface_checker.rb, line 24 def initialize(object) @object = object end
Public Instance Methods
implements(interface_name)
click to toggle source
# File lib/table_sync/utils/interface_checker.rb, line 28 def implements(interface_name) INTERFACES[interface_name].each do |method_name, options| unless object.respond_to?(method_name) raise_error(method_name, options) end unless include?(object.method(method_name).parameters, options[:parameters]) raise_error(method_name, options) end end self end
Private Instance Methods
filter(parameters)
click to toggle source
# File lib/table_sync/utils/interface_checker.rb, line 56 def filter(parameters) ignored_keys = %i[req block] # for req and block parameters types we can ignore names parameters.map { |param| ignored_keys.include?(param.first) ? [param.first] : param } end
include?(checked, expected)
click to toggle source
# File lib/table_sync/utils/interface_checker.rb, line 43 def include?(checked, expected) (filter(expected) - filter(checked)).empty? end
raise_error(method_name, options)
click to toggle source
# File lib/table_sync/utils/interface_checker.rb, line 47 def raise_error(method_name, options) raise TableSync::InterfaceError.new( object, method_name, options[:parameters], options[:description], ) end