famili 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZGFlYmM2NGYxNDVhN2IxOGJiZTA4NGJkNjE2YWNhOTZlYjE1OGZmMA==
5
+ data.tar.gz: !binary |-
6
+ MWU2OTdiZjQzMmI4NjYxZjU3ZmNhODhjN2VhMTE3ODUyZjc5N2U2ZA==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ YTNmNGRhYTE1M2I5YTMxNWZhNTEwYTQ0NjI2NDAzNWJlNzY4OWQ4NzQxZWUx
10
+ YjIyNzc3YzYyMzg2ZTA0YzIxNDU2Y2FlN2I2ZDk5OGE2Yzg2MjZhMzc5MzVm
11
+ ZTgwZmQzOTZlMDMzZDQ4YzI0NzgxZDM4MzIwODg4NWUwY2IxODk=
12
+ data.tar.gz: !binary |-
13
+ MTNhM2NkNDAzYjg5ZDAyZDAyY2FlMDQ5NjVhZGU2NzMzZmVmNzhhZjYxYmE3
14
+ OWRjOWRiNDk5MmY4MjVlOTM4NzczNDk4ODk1ZmYwY2I1NTUyMTI5M2U3ZTU3
15
+ ZTM2NjdmZDY0MzFjMGU3YzUyZTBhNzIwZGIwYjg3YTU2NzRhNjc=
data/lib/famili.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  $:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
2
2
  module Famili
3
3
  autoload :Mother,'famili/mother'
4
+ autoload :GrandMother, 'famili/grand_mother'
4
5
  end
data/lib/famili/child.rb CHANGED
@@ -1,66 +1,98 @@
1
- require 'famili/attributes'
2
-
3
1
  module Famili
4
2
  class Child < BasicObject
5
- attr_reader :mother
6
-
7
3
  def initialize(mother, attributes)
8
4
  @mother = mother
9
- @attributes = Attributes.new(attributes)
5
+ @attributes = attributes
6
+ @unresolved_attribute_names = attributes.keys.dup
7
+ @cached_attributes = {}
10
8
  end
11
9
 
12
- def born
13
- @model = @mother.instantiate(@attributes)
14
- @meta_class = @model.singleton_class
15
- @model.instance_variable_set(:@__famili_child__, self)
10
+ def [](name)
11
+ resolve_attribute(name)
12
+ end
13
+
14
+ def resolve_attributes(instance = nil, &block)
15
+ bind(instance, &block) if instance
16
+ resolve_attribute(unresolved_attribute_names.first) until unresolved_attribute_names.empty?
17
+ unbind if instance
18
+ instance
19
+ end
20
+
21
+ def bind(instance, &block)
22
+ @instance = instance
23
+ @resolve_callback = block
24
+ @instance.instance_variable_set(:@__famili_child__, self)
16
25
  define_method_stub(:method_missing) do |name, *args|
17
- mother = @__famili_child__.mother
26
+ mother = @__famili_child__.__send__(:mother)
18
27
  if mother.respond_to?(name)
19
28
  mother.send(name, *args)
29
+ elsif (value = @__famili_child__.__send__(:cached_attributes)[name])
30
+ value
20
31
  else
21
- send(@__famili_child__.munge(:method_missing), name, *args)
32
+ send(@__famili_child__.__send__(:munge, :method_missing), name, *args)
22
33
  end
23
34
  end
24
- @attributes.unresolved_names.each do |key|
25
- define_property_stub(key)
26
- end
27
- resolve_property(@attributes.unresolved_names.first) until @attributes.unresolved_names.empty?
35
+ @attributes.each { |attr_name, _| define_property_stub(attr_name) }
36
+ end
37
+
38
+ def unbind
39
+ @resolve_callback = nil
40
+ @attributes.each { |attr_name, _| undefine_property_stub(attr_name) }
28
41
  undefine_method_stub(:method_missing)
29
- @model
42
+ @instance.send(:remove_instance_variable, :@__famili_child__)
30
43
  end
31
44
 
32
- def munge(property_name)
33
- "__famili_child_proxied_#{property_name}"
45
+ private
46
+
47
+ attr_reader :mother, :unresolved_attribute_names, :cached_attributes
48
+
49
+ def meta_class
50
+ @instance.singleton_class
34
51
  end
35
52
 
36
- def resolve_property(name)
37
- undefine_property_stub(name)
38
- @model.send("#{name}=", @attributes.resolve(@model, name))
53
+ def munge(property_name)
54
+ "__famili_child_proxied_#{property_name}"
39
55
  end
40
56
 
41
57
  def define_property_stub(property_name)
42
58
  define_method_stub property_name do
43
- @__famili_child__.resolve_property(property_name)
44
- end if @model.respond_to?(property_name)
59
+ @__famili_child__[property_name]
60
+ end if @instance.respond_to?(property_name)
45
61
  end
46
62
 
47
63
  def undefine_property_stub(property_name)
48
- undefine_method_stub(property_name) if @meta_class.send(:method_defined?, munge(property_name))
64
+ undefine_method_stub(property_name) if meta_class.send(:method_defined?, munge(property_name))
49
65
  end
50
66
 
51
67
  def define_method_stub(method_name, &block)
52
- @meta_class.send(:alias_method, munge(method_name), method_name)
53
- @meta_class.send(:define_method, method_name, &block)
68
+ meta_class.send(:alias_method, munge(method_name), method_name)
69
+ meta_class.send(:define_method, method_name, &block)
54
70
  end
55
71
 
56
72
  def undefine_method_stub(method_name)
57
73
  munged_name = munge(method_name)
58
- if @meta_class.send(:method_defined?, munged_name)
59
- @meta_class.send(:alias_method, method_name, munged_name)
60
- @meta_class.send(:remove_method, munged_name)
74
+ if meta_class.send(:method_defined?, munged_name)
75
+ meta_class.send(:alias_method, method_name, munged_name)
76
+ meta_class.send(:remove_method, munged_name)
61
77
  else
62
- @meta_class.send(:remove_method, method_name)
78
+ meta_class.send(:remove_method, method_name)
63
79
  end
64
80
  end
81
+
82
+ def resolve_attribute(name)
83
+ @cached_attributes[name] ||=
84
+ if unresolved_attribute_names.delete(name)
85
+ attribute_value = @attributes[name]
86
+ if attribute_value.is_a?(::Proc)
87
+ attribute_value = @instance.instance_exec(&attribute_value)
88
+ elsif attribute_value.respond_to?(:call)
89
+ attribute_value = attribute_value.call
90
+ end
91
+ attribute_value = attribute_value.build if attribute_value.is_a?(::Famili::Father)
92
+ undefine_property_stub(name)
93
+ @resolve_callback.call(@instance, name, attribute_value) if @resolve_callback
94
+ attribute_value
95
+ end
96
+ end
65
97
  end
66
98
  end
data/lib/famili/father.rb CHANGED
@@ -19,17 +19,17 @@ module Famili
19
19
 
20
20
  def build(opts = {})
21
21
  attributes = merge(opts)
22
- model = Famili::Child.new(@mother, attributes).born
23
- yield model if block_given?
24
- @mother.before_save(model)
25
- model
22
+ instance = @mother.born(Famili::Child.new(@mother, attributes))
23
+ yield instance if block_given?
24
+ @mother.before_save(instance)
25
+ instance
26
26
  end
27
27
 
28
28
  def create(opts = {}, &block)
29
- model = build(opts, &block)
30
- @mother.save(model)
31
- @mother.after_create(model)
32
- model
29
+ instance = build(opts, &block)
30
+ @mother.save(instance)
31
+ @mother.after_create(instance)
32
+ instance
33
33
  end
34
34
 
35
35
  def produce_brothers(num, opts={}, init_block, &block)
@@ -24,6 +24,12 @@ module Famili
24
24
  self.class.model_class.new
25
25
  end
26
26
 
27
+ def born(child)
28
+ child.resolve_attributes(instantiate(child)) do |instance, name, value|
29
+ instance.send("#{name}=", value)
30
+ end
31
+ end
32
+
27
33
  def save(model)
28
34
  end
29
35
 
@@ -1,5 +1,5 @@
1
1
  module Famili
2
2
  module Version
3
- STRING = '1.2.0'
3
+ STRING = '1.3.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: famili
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
5
- prerelease:
4
+ version: 1.3.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - niquola
@@ -10,7 +9,7 @@ authors:
10
9
  autorequire:
11
10
  bindir: exe
12
11
  cert_chain: []
13
- date: 2013-08-21 00:00:00.000000000 Z
12
+ date: 2013-09-27 00:00:00.000000000 Z
14
13
  dependencies: []
15
14
  description: Yet another object mother pattern implementation.
16
15
  email:
@@ -19,7 +18,6 @@ extensions: []
19
18
  extra_rdoc_files: []
20
19
  files:
21
20
  - lib/famili.rb
22
- - lib/famili/attributes.rb
23
21
  - lib/famili/child.rb
24
22
  - lib/famili/class_attribute.rb
25
23
  - lib/famili/delegate.rb
@@ -30,6 +28,7 @@ files:
30
28
  - lib/famili/version.rb
31
29
  homepage: http://github.com/niquola/famili
32
30
  licenses: []
31
+ metadata: {}
33
32
  post_install_message:
34
33
  rdoc_options:
35
34
  - --charset=UTF-8
@@ -39,24 +38,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
39
38
  requirements:
40
39
  - - ! '>='
41
40
  - !ruby/object:Gem::Version
42
- hash: -1151566627510109189
43
41
  version: '0'
44
- segments:
45
- - 0
46
- none: false
47
42
  required_rubygems_version: !ruby/object:Gem::Requirement
48
43
  requirements:
49
44
  - - ! '>='
50
45
  - !ruby/object:Gem::Version
51
- hash: -1151566627510109189
52
46
  version: '0'
53
- segments:
54
- - 0
55
- none: false
56
47
  requirements: []
57
48
  rubyforge_project:
58
- rubygems_version: 1.8.24
49
+ rubygems_version: 2.1.3
59
50
  signing_key:
60
- specification_version: 3
61
- summary: famili-1.2.0
51
+ specification_version: 4
52
+ summary: famili-1.3.0
62
53
  test_files: []
@@ -1,27 +0,0 @@
1
- module Famili
2
- class Attributes
3
- attr :unresolved_names
4
-
5
- def initialize(attributes)
6
- @attributes = attributes
7
- @unresolved_names = attributes.keys
8
- end
9
-
10
- def [](name)
11
- (@cached_attributes ||= {})[name] ||= resolve(nil, name)
12
- end
13
-
14
- def resolve(model, name)
15
- if unresolved_names.delete(name)
16
- attribute_value = @attributes[name]
17
- if attribute_value.is_a?(::Proc)
18
- attribute_value = model.instance_exec(&attribute_value)
19
- elsif attribute_value.respond_to?(:call)
20
- attribute_value = attribute_value.call
21
- end
22
- attribute_value = attribute_value.build if attribute_value.is_a?(::Famili::Father)
23
- attribute_value
24
- end
25
- end
26
- end
27
- end