deep_dive 0.2.9 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.semver +2 -2
- data/README.rdoc +20 -2
- data/deep_dive.gemspec +2 -2
- data/lib/deep_dive/deep_dive.rb +30 -14
- data/spec/lib/deep_dive/deep_dive_spec.rb +7 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 142b15ce3e57aefd6e65e5f7efbb29b1fb2f3eef
|
4
|
+
data.tar.gz: 3fbe5520d074ea2aa56d4834fd57b09216dcac8d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 21500cd72ec277fbfb2c6605620f1b94cddcb83602ba6fe69bbd524c5d8a957162f264d7afff09d60c05eba5b68bf6a82979a2181ee6554efb68d5b97e0a3bb7
|
7
|
+
data.tar.gz: 078789351c3fffad438e160a3a0dc20f4d3f9264543be979a667f7e581742e2d83215c5dcd65605a6c8ffcd0bd4d6afbbb54ef498a932748c9303aa38569fde5
|
data/.semver
CHANGED
data/README.rdoc
CHANGED
@@ -87,6 +87,21 @@ which will basically do a deep dup of @foo.
|
|
87
87
|
Please see spec/lib/deep_dive/deep_dive_spec.rb for a more comprehensve example
|
88
88
|
of the above. Better documentation will be supplied shortly.
|
89
89
|
|
90
|
+
=== Patching
|
91
|
+
In some rare circumstances, you may need to patch an instance
|
92
|
+
variable in your object graph during deep copying. Like for
|
93
|
+
instance, when a child object is being cloned seprately from a different
|
94
|
+
parent to be associated with a new parent.
|
95
|
+
|
96
|
+
We introduce patching. The instance variable
|
97
|
+
|
98
|
+
@foo.parent = @oldparent
|
99
|
+
pf = @foo.dclone parent: @newparent
|
100
|
+
pf.parent.should == @newparent
|
101
|
+
|
102
|
+
And all variables named "parent" in the object graph will
|
103
|
+
pick up the new reference.
|
104
|
+
|
90
105
|
== Note Well
|
91
106
|
|
92
107
|
DeepDive is expected to undergo rapid evolution until it hits 1.0.0. I will take
|
@@ -94,8 +109,11 @@ every effort to keep the API backwards compatable until then.
|
|
94
109
|
|
95
110
|
== Release Notes
|
96
111
|
|
97
|
-
|
98
|
-
|
112
|
+
2015-07-07 0.3.0 -- Added debugging and deep patching based on
|
113
|
+
instance variable names.
|
114
|
+
|
115
|
+
2014-07-27 0.2.0 -- Implemented the exclusion block,
|
116
|
+
made gem restrictive to Ruby 2.x and higher.
|
99
117
|
|
100
118
|
== Copyright
|
101
119
|
|
data/deep_dive.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: deep_dive 0.
|
5
|
+
# stub: deep_dive 0.3.0 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "deep_dive"
|
9
|
-
s.version = "0.
|
9
|
+
s.version = "0.3.0"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib"]
|
data/lib/deep_dive/deep_dive.rb
CHANGED
@@ -28,13 +28,18 @@ module DeepDive
|
|
28
28
|
|
29
29
|
module API
|
30
30
|
# #ddup is a Deep Dive's replacement for #dup.
|
31
|
-
def ddup
|
32
|
-
_replicate dupit: true
|
31
|
+
def ddup(**patch)
|
32
|
+
_replicate dupit: true, patch: _patch_at(**patch)
|
33
33
|
end
|
34
34
|
|
35
35
|
# #dclone is Deep Dive's replacement for #clone.
|
36
|
-
def dclone
|
37
|
-
_replicate dupit: false
|
36
|
+
def dclone(**patch)
|
37
|
+
_replicate dupit: false, patch: _patch_at(**patch)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Do not use. Internal only.
|
41
|
+
def _patch_at(**p)
|
42
|
+
Hash[p.map{|k, v| ["@#{k}".to_sym, v]}]
|
38
43
|
end
|
39
44
|
end
|
40
45
|
|
@@ -48,8 +53,11 @@ module DeepDive
|
|
48
53
|
include API
|
49
54
|
end
|
50
55
|
|
56
|
+
|
51
57
|
# Not meant to be called externally. Use either ddup or dclone.
|
52
|
-
|
58
|
+
# The patch list will take the value and use that wherver
|
59
|
+
# it finds the key instance variable down the object graph.
|
60
|
+
def _replicate(dupit: true, oc: {}, patch: {})
|
53
61
|
unless oc.member? self
|
54
62
|
puts "DeepDive: replicating #{self.class}:<#{self.object_id.to_s(16)}>" if DeepDive::verbose?
|
55
63
|
|
@@ -58,6 +66,7 @@ module DeepDive
|
|
58
66
|
else
|
59
67
|
clone
|
60
68
|
end
|
69
|
+
|
61
70
|
copy.instance_variables.map do |var|
|
62
71
|
[var, instance_variable_get(var)]
|
63
72
|
end.reject do |var, ob|
|
@@ -65,8 +74,15 @@ module DeepDive
|
|
65
74
|
end.reject do |var, ob|
|
66
75
|
self.class.excluded?(var, self)
|
67
76
|
end.each do |var, value|
|
68
|
-
|
69
|
-
|
77
|
+
unless patch.member? var
|
78
|
+
puts "DeepDive: rep instance var #{self.class}.#{var}(#{value.class}:<#{value.object_id.to_s(16)}>)" if DeepDive::verbose?
|
79
|
+
copy.instance_variable_set(var, value._replicate(oc: oc,
|
80
|
+
dupit: dupit,
|
81
|
+
patch: patch))
|
82
|
+
else
|
83
|
+
puts "DeepDive: PATCH instance var #{self.class}.#{var}(#{patch[var].class}:<#{patch[var].object_id.to_s(16)}>)" if DeepDive::verbose?
|
84
|
+
copy.instance_variable_set(var, patch[var])
|
85
|
+
end
|
70
86
|
end
|
71
87
|
end
|
72
88
|
oc[self]
|
@@ -76,9 +92,9 @@ module DeepDive
|
|
76
92
|
# differently.
|
77
93
|
module ::Enumerable
|
78
94
|
# FIXME: clean up the code a bit, this could be better structured.
|
79
|
-
def _ob_maybe_repl(v: nil, dupit: nil, oc: nil)
|
95
|
+
def _ob_maybe_repl(v: nil, dupit: nil, oc: nil, patch: {})
|
80
96
|
if v.respond_to? :_replicate
|
81
|
-
v._replicate(oc: oc, dupit: dupit)
|
97
|
+
v._replicate(oc: oc, dupit: dupit, patch: patch)
|
82
98
|
else
|
83
99
|
v
|
84
100
|
end
|
@@ -91,7 +107,7 @@ module DeepDive
|
|
91
107
|
# Here all the logic will be present to handle the "special case"
|
92
108
|
# enumerables. Most notedly, Hash and Array will require special
|
93
109
|
# treatment.
|
94
|
-
def _add(v: nil, dupit: nil, oc: nil)
|
110
|
+
def _add(v: nil, dupit: nil, oc: nil, patch: {})
|
95
111
|
unless _pairs?
|
96
112
|
case
|
97
113
|
when self.kind_of?(::Set)
|
@@ -101,7 +117,7 @@ module DeepDive
|
|
101
117
|
raise DeepDiveException.new("Don't know how to add new elements for class #{self.class}")
|
102
118
|
end
|
103
119
|
else
|
104
|
-
self[v.first] = _ob_maybe_repl(v: v.last, dupit: dupit, oc: oc)
|
120
|
+
self[v.first] = _ob_maybe_repl(v: v.last, dupit: dupit, oc: oc, patch: patch)
|
105
121
|
end
|
106
122
|
end
|
107
123
|
|
@@ -122,10 +138,10 @@ module DeepDive
|
|
122
138
|
#
|
123
139
|
# FIXME: We will initially not handle Enumberables that have instance variables.
|
124
140
|
# FIXME: This issue will be addressed at a later date.
|
125
|
-
def _replicate(dupit: true, oc: {})
|
141
|
+
def _replicate(dupit: true, oc: {}, patch: {})
|
126
142
|
unless oc.member? self
|
127
143
|
self.inject(oc[self] = self.class.new) do |copy, v|
|
128
|
-
copy._add(v: v, dupit: dupit, oc: oc)
|
144
|
+
copy._add(v: v, dupit: dupit, oc: oc, patch: patch)
|
129
145
|
copy
|
130
146
|
end
|
131
147
|
end
|
@@ -135,7 +151,7 @@ module DeepDive
|
|
135
151
|
|
136
152
|
module CMeth
|
137
153
|
@@exclusion = []
|
138
|
-
# exclusion list of instance variables to dup/clone
|
154
|
+
# exclusion list of instance variables to NOT dup/clone
|
139
155
|
def exclude(*list, &block)
|
140
156
|
@@exclusion << list.map { |s| "@#{s}".to_sym }
|
141
157
|
@@exclusion.flatten!
|
@@ -30,6 +30,7 @@ describe DeepDive do
|
|
30
30
|
@foo = Foo.new
|
31
31
|
@bar = Bar.new
|
32
32
|
@foobar = FooBar.new
|
33
|
+
@patch = FooBar.new
|
33
34
|
@fbf = FooBarFoo.new
|
34
35
|
|
35
36
|
@foobar.arr = [@foo, @bar, @foobar, "Just a string"]
|
@@ -48,7 +49,7 @@ describe DeepDive do
|
|
48
49
|
@fbf.fc = @foobar
|
49
50
|
@fbf.frecur = @fbf
|
50
51
|
@fbf.fexcludeme = Foo.new
|
51
|
-
|
52
|
+
DeepDive.verbose = true
|
52
53
|
end
|
53
54
|
|
54
55
|
context 'debugging' do
|
@@ -81,6 +82,11 @@ describe DeepDive do
|
|
81
82
|
cfoo.a.should_not == @foo.a
|
82
83
|
end
|
83
84
|
|
85
|
+
it 'patches' do
|
86
|
+
pf = @foo.dclone b: @patch
|
87
|
+
pf.b.should == @patch
|
88
|
+
end
|
89
|
+
|
84
90
|
it 'handles hash cloning properly' do
|
85
91
|
cfoo = @foo.dclone
|
86
92
|
cfoo.h[1].should == "one"
|