Class: Constructable::Constructor

Inherits:
Object
  • Object
show all
Defined in:
lib/constructable/constructor.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(base) ⇒ Constructor

Returns a new instance of Constructor.



5
6
7
8
9
10
11
12
# File 'lib/constructable/constructor.rb', line 5

def initialize(base)
  @attributes = []
  @module = Module.new
  @base = base
  @base.send :include, @module
  self.redefine_new_calling
  self.define_concstructable_attributes_method
end

Instance Attribute Details

#attributesObject

Returns the value of attribute attributes.



3
4
5
# File 'lib/constructable/constructor.rb', line 3

def attributes
  @attributes
end

Instance Method Details

#construct(constructor_hash, obj) ⇒ Object



59
60
61
62
63
64
# File 'lib/constructable/constructor.rb', line 59

def construct(constructor_hash, obj)
  constructor_hash ||= {}
  @attributes.each do |attribute|
    obj.instance_variable_set attribute.ivar_symbol, attribute.process(constructor_hash[attribute.name])
  end
end

#define_attributes(attributes) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/constructable/constructor.rb', line 43

def define_attributes(attributes)
  attributes = generate_attributes(attributes)
  @attributes.concat attributes

  attributes = @attributes
  attributes.each do |attribute|
    @module.module_eval do
      attr_reader attribute.name if attribute.readable

      define_method(attribute.attr_writer_symbol) do |value|
        instance_variable_set attribute.ivar_symbol, attribute.process(value)
      end if attribute.writable
    end
  end
end

#define_concstructable_attributes_methodObject



78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/constructable/constructor.rb', line 78

def define_concstructable_attributes_method
  constructor = self
  @base.module_eval do
    define_method :constructable_attributes do
      Hash[
        constructor.attributes
        .map { |a| [a.name,instance_variable_get(a.ivar_symbol)] }
        .select(&:last)
      ]
    end
  end
end

#generate_attributes(attributes) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
# File 'lib/constructable/constructor.rb', line 66

def generate_attributes(attributes)
  options = if Hash === attributes.last
    attributes.pop
  else
    {}
  end

  attributes.map do |attribute|
    Attribute.new(attribute, options)
  end
end

#redefine_new(klass) ⇒ Object



32
33
34
35
36
37
38
39
40
41
# File 'lib/constructable/constructor.rb', line 32

def redefine_new(klass)
  constructor = self
  klass.define_singleton_method(:new) do |*args, &block|
    obj = self.allocate
    constructor_hash = Hash === args.last ? args.last : {}
    constructor.construct(constructor_hash, obj)
    obj.send :initialize, *args, &block
    obj
  end
end

#redefine_new_callingObject



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/constructable/constructor.rb', line 14

def redefine_new_calling
  case @base
  when Class
    self.redefine_new(@base)
  when Module
    constructor = self
    redefine_new_logic = proc do |base|
      base.instance_variable_set(:@constructor, constructor)
      if Class == base.class
        constructor.redefine_new(base)
      elsif Module == base.class
        base.define_singleton_method :included, &redefine_new_logic
      end
    end
    @base.define_singleton_method :included, &redefine_new_logic
  end
end