Class: Famili::Child

Inherits:
BasicObject
Defined in:
lib/famili/child.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(mother, attributes) ⇒ Child



7
8
9
10
# File 'lib/famili/child.rb', line 7

def initialize(mother, attributes)
  @mother = mother
  @attributes = Attributes.new(attributes)
end

Instance Attribute Details

#motherObject (readonly)

Returns the value of attribute mother.



5
6
7
# File 'lib/famili/child.rb', line 5

def mother
  @mother
end

Instance Method Details

#bornObject



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

def born
  @model = @mother.instantiate(@attributes)
  @meta_class = @model.singleton_class
  @model.instance_variable_set(:@__famili_child__, self)
  define_method_stub(:method_missing) do |name, *args|
    mother = @__famili_child__.mother
    if mother.respond_to?(name)
      mother.send(name, *args)
    else
      send(@__famili_child__.munge(:method_missing), name, *args)
    end
  end
  @attributes.unresolved_names.each do |key|
    define_property_stub(key)
  end
  resolve_property(@attributes.unresolved_names.first) until @attributes.unresolved_names.empty?
  undefine_method_stub(:method_missing)
  @model
end

#define_method_stub(method_name, &block) ⇒ Object



51
52
53
54
# File 'lib/famili/child.rb', line 51

def define_method_stub(method_name, &block)
  @meta_class.send(:alias_method, munge(method_name), method_name)
  @meta_class.send(:define_method, method_name, &block)
end

#define_property_stub(property_name) ⇒ Object



41
42
43
44
45
# File 'lib/famili/child.rb', line 41

def define_property_stub(property_name)
  define_method_stub property_name do
    @__famili_child__.resolve_property(property_name)
  end if @model.respond_to?(property_name)
end

#munge(property_name) ⇒ Object



32
33
34
# File 'lib/famili/child.rb', line 32

def munge(property_name)
  "__famili_child_proxied_#{property_name}"
end

#resolve_property(name) ⇒ Object



36
37
38
39
# File 'lib/famili/child.rb', line 36

def resolve_property(name)
  undefine_property_stub(name)
  @model.send("#{name}=", @attributes.resolve(@model, name))
end

#undefine_method_stub(method_name) ⇒ Object



56
57
58
59
60
61
62
63
64
# File 'lib/famili/child.rb', line 56

def undefine_method_stub(method_name)
  munged_name = munge(method_name)
  if @meta_class.send(:method_defined?, munged_name)
    @meta_class.send(:alias_method, method_name, munged_name)
    @meta_class.send(:remove_method, munged_name)
  else
    @meta_class.send(:remove_method, method_name)
  end
end

#undefine_property_stub(property_name) ⇒ Object



47
48
49
# File 'lib/famili/child.rb', line 47

def undefine_property_stub(property_name)
  undefine_method_stub(property_name) if @meta_class.send(:method_defined?, munge(property_name))
end