Module: BBLib::SimpleInit::ClassMethods

Defined in:
lib/mixins/simple_init.rb

Instance Method Summary collapse

Instance Method Details

#_classObject



147
148
149
# File 'lib/mixins/simple_init.rb', line 147

def _class
  self.to_s
end

#_super_init_typeObject

Used to load the init type of the nearest ancestor for inheritance.



121
122
123
124
125
126
127
# File 'lib/mixins/simple_init.rb', line 121

def _super_init_type
  ancestors.each do |ancestor|
    next if ancestor == self
    return ancestor.init_type if ancestor.respond_to?(:init_type)
  end
  :strict
end

#ancestor_init_foundation_methodObject



102
103
104
105
106
107
108
# File 'lib/mixins/simple_init.rb', line 102

def ancestor_init_foundation_method
  anc = ancestors.find do |a|
    next if a == self
    a.respond_to?(:init_foundation_method)
  end
  anc ? anc.init_foundation_method : :_class
end

#build_descendant(name, namespace: parent_namespace) ⇒ Object

Dynamically create a new class based on this one. By default this class is generated in the same namespace as the parent class. A custom namespace can be passed in using the named argument :namespace.



132
133
134
# File 'lib/mixins/simple_init.rb', line 132

def build_descendant(name, namespace: parent_namespace)
  namespace.const_set(name, Class.new(self))
end

#init_foundationObject

If true, this allows the overriden new method to generate descendants from its constructors.



75
76
77
# File 'lib/mixins/simple_init.rb', line 75

def init_foundation
  @init_foundation ||= false
end

#init_foundation=(toggle) ⇒ Object

Sets the init_foundation variable to true of false. When false, the new method behaves like any other class. If true, the new method can instantiate child classes using the :_class named parameter.



82
83
84
# File 'lib/mixins/simple_init.rb', line 82

def init_foundation=(toggle)
  @init_foundation = toggle
end

#init_foundation_compare(&block) ⇒ Object



91
92
93
94
# File 'lib/mixins/simple_init.rb', line 91

def init_foundation_compare(&block)
  @init_foundation_compare = block if block
  @init_foundation_compare
end

#init_foundation_method(method = nil) ⇒ Object



86
87
88
89
# File 'lib/mixins/simple_init.rb', line 86

def init_foundation_method(method = nil)
  @init_foundation_method = method if method
  @init_foundation_method ||= ancestor_init_foundation_method
end

#init_type(type = nil) ⇒ Object

Sets or returns the current init type for this class. Available types are:

> :strict = Unknown named arguments will raise an error.

> :loose = Unknown named arguments are ignored.

Raises:

  • (ArgumentError)


114
115
116
117
118
# File 'lib/mixins/simple_init.rb', line 114

def init_type(type = nil)
  return @init_type ||= _super_init_type unless type
  raise ArgumentError, "Unknown init type '#{type}'. Must be #{INIT_TYPES.join_terms('or', encapsulate: "'")}." unless INIT_TYPES.include?(type)
  @init_type = type
end

#new(*args, &block) ⇒ Object

Overriden new method that allows parent classes to dynamically generate instantiations of descendants by using the named init_foundation_method argument.



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/mixins/simple_init.rb', line 55

def new(*args, &block)
  named = BBLib.named_args(*args)
  if init_foundation && named[init_foundation_method] && ((named[init_foundation_method] != self.send(init_foundation_method)) rescue false)
    klass = [self, descendants].flatten.find do |k|
      if init_foundation_compare
        init_foundation_compare.call(k.send(init_foundation_method), named[init_foundation_method])
      else
        k.send(init_foundation_method).to_s == named[init_foundation_method].to_s
      end
    end
    raise ArgumentError, "Unknown #{init_foundation_method} \"#{named[init_foundation_method]}\"" unless klass
    klass == self ? super : klass.new(*args, &block)
  else
    super
  end
end

#parent_namespaceObject

Returns the nearest parent namespace to thi current class. Object is returned if this class is not in a namespace.



138
139
140
141
142
143
144
145
# File 'lib/mixins/simple_init.rb', line 138

def parent_namespace
  parent = self.to_s.split('::')[0..-2].join('::')
  if parent.empty?
    return Object
  else
    Object.const_get(parent)
  end
end

#setup_init_foundation(method, &block) ⇒ Object



96
97
98
99
100
# File 'lib/mixins/simple_init.rb', line 96

def setup_init_foundation(method, &block)
  self.init_foundation = true
  self.init_foundation_method(method)
  self.init_foundation_compare(&block) if block
end