class Karafka::Helpers::ClassMatcher
Class used to autodetect corresponding classes that are internally inside Karafka
framework It is used among others to match:
consumer => responder
Constants
- CONSTANT_REGEXP
Regexp used to remove any non classy like characters that might be in the consumer class name (if defined dynamically, etc)
Public Class Methods
@param klass [Class] class to which we want to find a corresponding class @param from [String] what type of object is it (based on postfix name part) @param to [String] what are we looking for (based on a postfix name part) @example Consumer that has a corresponding responder
matcher = Karafka::Helpers::ClassMatcher.new(SuperConsumer, 'Consumer', 'Responder') matcher.match #=> SuperResponder
@example Consumer without a corresponding responder
matcher = Karafka::Helpers::ClassMatcher.new(Super2Consumer, 'Consumer', 'Responder') matcher.match #=> nil
# File lib/karafka/helpers/class_matcher.rb, line 24 def initialize(klass, from:, to:) @klass = klass @from = from @to = to end
Public Instance Methods
@return [Class] matched class @return [nil] nil if we couldn't find matching class
# File lib/karafka/helpers/class_matcher.rb, line 32 def match return nil if name.empty? return nil unless scope.const_defined?(name) matching = scope.const_get(name) same_scope?(matching) ? matching : nil end
@return [String] name of a new class that we're looking for @note This method returns name of a class without a namespace @example From SuperConsumer matching responder
matcher.name #=> 'SuperResponder'
@example From Namespaced::Super2Consumer matching responder
matcher.name #=> Super2Responder
# File lib/karafka/helpers/class_matcher.rb, line 46 def name inflected = +@klass.to_s.split('::').last.to_s # We inject the from into the name just in case it is missing as in a situation like # that it would just sanitize the name without adding the "to" postfix. # It could create cases when we want to build for example a responder to a consumer # that does not have the "Consumer" postfix and would do nothing returning the same name. # That would be bad as the matching classes shouldn't be matched to themselves. inflected << @from unless inflected.include?(@from) inflected.gsub!(@from, @to) inflected.gsub!(CONSTANT_REGEXP, '') inflected end
@return [Class, Module] class or module in which we're looking for a matching
# File lib/karafka/helpers/class_matcher.rb, line 60 def scope scope_of(@klass) end
Private Instance Methods
@param matching [Class] class of which scope we want to check @return [Boolean] true if the scope of class is the same as scope of matching
# File lib/karafka/helpers/class_matcher.rb, line 83 def same_scope?(matching) scope == scope_of(matching) end
@param klass [Class] class for which we want to extract it's enclosing class/module @return [Class, Module] enclosing class/module @return [::Object] object if it was a root class
@example Non-namespaced class
scope_of(SuperClass) #=> Object
@example Namespaced class
scope_of(Abc::SuperClass) #=> Abc
# File lib/karafka/helpers/class_matcher.rb, line 74 def scope_of(klass) enclosing = klass.to_s.split('::')[0...-1] return ::Object if enclosing.empty? ::Object.const_get(enclosing.join('::')) end