Module: BBLib::SimpleInit::ClassMethods

Defined in:
lib/bblib/core/mixins/simple_init.rb

Instance Method Summary collapse

Instance Method Details

#_classObject



174
175
176
# File 'lib/bblib/core/mixins/simple_init.rb', line 174

def _class
  self.to_s
end

#_super_collect_methodObject



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

def _super_collect_method
    ancestors.each do |ancestor|
      next if ancestor == self
      return ancestor.collect_method if ancestor.respond_to?(:collect_method)
    end
    :attributes
end

#_super_init_typeObject

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



148
149
150
151
152
153
154
# File 'lib/bblib/core/mixins/simple_init.rb', line 148

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



129
130
131
132
133
134
135
# File 'lib/bblib/core/mixins/simple_init.rb', line 129

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.



159
160
161
# File 'lib/bblib/core/mixins/simple_init.rb', line 159

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

#collect_method(name = nil) ⇒ Object



116
117
118
119
# File 'lib/bblib/core/mixins/simple_init.rb', line 116

def collect_method(name = nil)
  @collect_method = name if name
  @collect_method ||= _super_collect_method
end

#init_foundationObject

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



85
86
87
# File 'lib/bblib/core/mixins/simple_init.rb', line 85

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.



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

def init_foundation=(toggle)
  @init_foundation = toggle
end

#init_foundation_compare(&block) ⇒ Object



101
102
103
104
# File 'lib/bblib/core/mixins/simple_init.rb', line 101

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

#init_foundation_default_classObject



112
113
114
# File 'lib/bblib/core/mixins/simple_init.rb', line 112

def init_foundation_default_class
  self
end

#init_foundation_method(method = nil) ⇒ Object



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

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)


141
142
143
144
145
# File 'lib/bblib/core/mixins/simple_init.rb', line 141

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.



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/bblib/core/mixins/simple_init.rb', line 63

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)
  elsif named[init_foundation_method].nil? && init_foundation_default_class != self && init_foundation_default_class < self
    init_foundation_default_class.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.



165
166
167
168
169
170
171
172
# File 'lib/bblib/core/mixins/simple_init.rb', line 165

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



106
107
108
109
110
# File 'lib/bblib/core/mixins/simple_init.rb', line 106

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