Class: Htmless::DynamicClasses::Classes

Inherits:
Object
  • Object
show all
Defined in:
lib/htmless/dynamic_classes.rb

Instance Attribute Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (Classes) initialize(base)

A new instance of Classes



81
82
83
84
85
86
87
# File 'lib/htmless/dynamic_classes.rb', line 81

def initialize(base)
  raise unless base.is_a? Class
  @base              = base
  @class_definitions = { }
  @class_extensions  = { }
  @classes           = { }
end

Instance Attribute Details

- (Object) base (readonly)

Returns the value of attribute base



79
80
81
# File 'lib/htmless/dynamic_classes.rb', line 79

def base
  @base
end

- (Object) class_definitions (readonly)

Returns the value of attribute class_definitions



79
80
81
# File 'lib/htmless/dynamic_classes.rb', line 79

def class_definitions
  @class_definitions
end

- (Object) class_extensions(name) (readonly, private)

Returns the value of attribute class_extensions



79
80
81
# File 'lib/htmless/dynamic_classes.rb', line 79

def class_extensions
  @class_extensions
end

- (Object) classes (readonly)

Returns the value of attribute classes



79
80
81
# File 'lib/htmless/dynamic_classes.rb', line 79

def classes
  @classes
end

Instance Method Details

- (Class) [](name)

Defined class

Returns:

  • (Class)

    defined class



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/htmless/dynamic_classes.rb', line 122

def [](name)
  return @classes[name] if @classes[name]
  return nil unless klass_definition = class_definition(name)

  superclass = case klass_definition.superclass_or_name
                 when Symbol then
                   self[klass_definition.superclass_or_name]
                 when Class then
                   klass = Class.new(klass_definition.superclass_or_name)
                   klass.send :include, Describable
                   klass._description = "Describable#{klass_definition.superclass_or_name}"
                   klass
                 when nil then
                   DescribableClass
               end

  set_up_klass = lambda do |klass, description, block|
    klass._description = description
    klass.instance_variable_set :@dynamic_class_base, base
    klass.singleton_class.send :attr_reader, :dynamic_class_base
    klass.class_eval &block
  end

  klass = Class.new(superclass)
  set_up_klass.call klass, "#{base}.dc[:#{klass_definition.name}]", klass_definition.definition

  class_extensions(name).each do |klass_extension|
    klass = Class.new klass
    set_up_klass.call klass, "#{base}.dc[:#{klass_extension.name}]", klass_extension.definition
  end

  @classes[name] = klass
end

- (Object) ancestor (private)



174
175
176
# File 'lib/htmless/dynamic_classes.rb', line 174

def ancestor
  @base.superclass.dynamic_classes if @base.superclass.kind_of?(DynamicClasses)
end

- (Object) ancestors (private)



170
171
172
# File 'lib/htmless/dynamic_classes.rb', line 170

def ancestors
  ([self] + [*(ancestor.ancestors if ancestor)]).compact
end

- (Object) class_definition(name) (private)



162
163
164
# File 'lib/htmless/dynamic_classes.rb', line 162

def class_definition(name)
  @class_definitions[name] or (ancestor.send :class_definition, name if ancestor)
end

- (Object) class_names



156
157
158
# File 'lib/htmless/dynamic_classes.rb', line 156

def class_names
  ancestors.map(&:class_definitions).map(&:keys).flatten
end

- (Object) def_class(name, superclass_or_name = nil) { ... }

define a class when Symbol then dynamic class is found when Class then this class is used when nil then Object is used

Parameters:

  • name (Symbol)
  • superclass_or_name (Symbol, Class, nil) (defaults to: nil)

Yields:

  • definition block is evaluated inside the class defining it

Raises:

  • (ArgumentError)


96
97
98
99
100
101
102
103
104
# File 'lib/htmless/dynamic_classes.rb', line 96

def def_class(name, superclass_or_name = nil, &definition)
  raise ArgumentError, "name is not a Symbol" unless name.is_a?(Symbol)
  unless superclass_or_name.is_a?(Symbol) || superclass_or_name.is_a?(Class) || superclass_or_name.nil?
    raise ArgumentError, "superclass_or_name is not a Symbol, Class or nil"
  end
  raise ArgumentError, "definition is nil" unless definition
  raise ArgumentError, "Class #{name} already defined" if class_definition(name)
  @class_definitions[name] = ClassDefinition.new(name, base, superclass_or_name, definition)
end

- (Object) extend_class(name) { ... }

extends already defined class by adding a child,

Parameters:

  • name (Symbol)

Yields:

  • definition block is evaluated inside the class extending it

Raises:

  • (ArgumentError)


109
110
111
112
113
114
# File 'lib/htmless/dynamic_classes.rb', line 109

def extend_class(name, &definition)
  raise ArgumentError, "name is not a Symbol" unless name.is_a?(Symbol)
  raise ArgumentError, "definition is nil" unless definition
  raise ArgumentError, "Class #{name} not defined" unless class_definition(name)
  @class_extensions[name] = ClassExtension.new(name, base, definition)
end

- (Object) load!

triggers loading of all defined classes



117
118
119
# File 'lib/htmless/dynamic_classes.rb', line 117

def load!
  class_names.each { |name| self[name] }
end