full_dup 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e29b1fda9c75d8b3d58009be5e0a05cdbb4900d0
4
- data.tar.gz: 12eaab0453df9c9929cba76476eef2afe49f5768
3
+ metadata.gz: 20cf85cb4234f06a7460867e7ea8106d39354c23
4
+ data.tar.gz: d6a798fe6cd7b325372d97b70b1502229f30fb09
5
5
  SHA512:
6
- metadata.gz: d528171d9e4b7fd69372df61f51d50e90a67357275e3735692fceb3c8fbe26b3afe8a311fd26eecc5dead476693fbdee927dc0a6c6cf669b18ed7af3c164d5f0
7
- data.tar.gz: d2922af5bc54fb610c6ebcf752df513e1f86c4f92185bbbb30dd94f90f18ff2726b38d5b32e4ed83b59f0b47db75f3e871ec32c4d97998b5c80ebfdf9f8794b7
6
+ metadata.gz: 1dfd98c630f82771af60cc0edc6db998258e1e6dcdbc39062a8129194244c34e725df68bfaa12b63a5feb1d8d10fd5e16c0b707902e1ed7a1de716d697ccb344
7
+ data.tar.gz: e47dcb7ba1044b94894e45c2241722dfee313b5b51ae93e32a1865945b6fa3d1221425e14a39704dd4402d383d392683095337df49557fca9225aac55611955e
data/README.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # FullDup
2
2
 
3
+ The full_dup gem adds the full_dup method to all objects descended from the
4
+ Object class. While this gem makes extensive use of monkey patching, it does
5
+ not modify the behaviour of any existing methods. This is done to minimize
6
+ the risk of breaking any existing code.
7
+
8
+ New for version 0.0.6, now 84% faster (at least in my tests).
9
+
3
10
  The standard dup method creates a fresh instance of most (non-scalar) objects
4
11
  but does not process internal state. This internal state remains aliased in the
5
12
  duplicated copy. The full_dup method digs deep and makes copies of these
@@ -13,13 +20,24 @@ it does mean that the dup operation must be applied with great care.
13
20
 
14
21
  Unlike the standard dup method, the full\_dup method does not throw an
15
22
  exception when it sees un-duppable value objects like 42 or true. These values
16
- simply return themselves. This is correct because those types of objects do
17
- not _need_ to be duped. Instead of having a fit, the code just works!
23
+ simply return themselves. This is deemed correct because those types of objects
24
+ are immutable and do not need to be duped. Instead of raising an exception,
25
+ the code returns the immutable object instead.
18
26
 
19
27
  Another issue that this gem deals with is that of data with looping reference
20
28
  chains. To handle this, the code tracks object ID values and does not re-dup
21
29
  data that has already been duped. Thus even nasty edge cases are handled
22
- without any special effort on the part of the application programmer.
30
+ without any special effort on the part of the application programmer. Note though
31
+ that this also means that it is important that the object id be correctly
32
+ implemented. Fortunately, this is done by default in Ruby.
33
+
34
+ If you wish to implement your own object id for your own special classes:
35
+ 1. Don't! If object_id is broken,
36
+ then full_dup (and a whole lot of other things too) will also be broken!
37
+ 2. It's all on you to do as good a job as Ruby. Like the Ruby object id method,
38
+ your method must create id values that are unique to each object and are perfectly
39
+ repeatable for that object.
40
+ 3. Really DON'T! I have never found a valid reason for doing so. I doubt that one exists.
23
41
 
24
42
  ## Family Overview
25
43
 
@@ -93,20 +111,46 @@ array:
93
111
  ```ruby
94
112
  my_array.define_singleton_method(:full_dup_exclude) { [0, 1] }
95
113
  ```
96
- <br>**Possible Red Flag** There is a catch here. The dup method does _not_
97
- duplicate singleton methods (unlike the clone method). Thus any duplicates
98
- made in this manner will lose the attached full_dup_exclude method. If it is
99
- important to retain singleton methods, consider using the full_clone gem
100
- instead.
114
+ <br>**Possible Red Flag** There is a catch here. The dup and full_dup methods
115
+ do not duplicate singleton methods (unlike the clone and full_clone methods).
116
+ Thus any duplicates made in this manner will lose the attached full_dup_exclude
117
+ method. If it is important to retain singleton methods, consider using the
118
+ full_clone gem instead.
101
119
 
102
- ## Notes
120
+ ### irbt
103
121
 
104
- The full_dup gem tracks its progress and handles data objects that
105
- contain loops, cycles, and other forms of recursion. In order to do this,
106
- it relies heavily on the object_id property of the data being copied.
107
- If object_id is broken, then full_dup and hashes and ... will also be
108
- broken!
122
+ The root folder of the full_dup gem contains the file irbt.rb. This program
123
+ opens up the irb repl with the full_dup gem preloaded and is useful for trying
124
+ out the gem interactively.
109
125
 
126
+ By default, irbt will load the system gem version of full dup. The following
127
+ interactive session demonstrates the difference between dup and full_dup
128
+
129
+ ```
130
+ C:\Sites\full_dup>ruby irbt.rb
131
+ Starting an IRB console with full_dup loaded.
132
+ full_dup loaded from gem: 0.0.5
133
+ irb(main):001:0> a = ["a", "b", "c"]
134
+ => ["a", "b", "c"]
135
+ irb(main):002:0> b = a.dup
136
+ => ["a", "b", "c"]
137
+ irb(main):003:0> c = a.full_dup
138
+ => ["a", "b", "c"]
139
+ irb(main):004:0> a[0] << "foo"
140
+ => "afoo"
141
+ irb(main):005:0> a
142
+ => ["afoo", "b", "c"]
143
+ irb(main):006:0> b
144
+ => ["afoo", "b", "c"]
145
+ irb(main):007:0> c
146
+ => ["a", "b", "c"]
147
+ irb(main):008:0>
148
+ ```
149
+ To load the local copy of full_dup use:
150
+ ```
151
+ >ruby irbt.rb local #optional irb args go here.
152
+ #etc etc etc...
153
+ ```
110
154
 
111
155
  ## Contributing
112
156
 
@@ -7,14 +7,20 @@ class Array
7
7
  progress[object_id] = result = dup
8
8
  exclude = full_dup_exclude
9
9
 
10
- each_index do |name|
11
-
12
- unless exclude.include?(name)
10
+ if exclude.empty?
11
+ each_index do |name|
13
12
  value = result[name]
14
13
  value = progress[value.object_id] || value.full_dup(progress)
15
14
  result[name] = value
16
15
  end
17
-
16
+ else
17
+ each_index do |name|
18
+ unless exclude.include?(name)
19
+ value = result[name]
20
+ value = progress[value.object_id] || value.full_dup(progress)
21
+ result[name] = value
22
+ end
23
+ end
18
24
  end
19
25
 
20
26
  result
data/lib/full_dup/hash.rb CHANGED
@@ -7,14 +7,20 @@ class Hash
7
7
  progress[object_id] = result = dup
8
8
  exclude = full_dup_exclude
9
9
 
10
- each_key do |name|
11
-
12
- unless exclude.include?(name)
10
+ if exclude.empty?
11
+ each_key do |name|
13
12
  value = result[name]
14
13
  value = progress[value.object_id] || value.full_dup(progress)
15
14
  result[name] = value
16
15
  end
17
-
16
+ else
17
+ each_key do |name|
18
+ unless exclude.include?(name)
19
+ value = result[name]
20
+ value = progress[value.object_id] || value.full_dup(progress)
21
+ result[name] = value
22
+ end
23
+ end
18
24
  end
19
25
 
20
26
  result
@@ -12,14 +12,20 @@ class Object
12
12
  progress[object_id] = result = dup
13
13
  exclude = full_dup_exclude
14
14
 
15
- instance_variables.each do |name|
16
-
17
- unless exclude.include?(name)
15
+ if exclude.empty?
16
+ instance_variables.each do |name|
18
17
  value = result.instance_variable_get(name)
19
18
  value = progress[value.object_id] || value.full_dup(progress)
20
19
  result.instance_variable_set(name, value)
21
20
  end
22
-
21
+ else
22
+ instance_variables.each do |name|
23
+ unless exclude.include?(name)
24
+ value = result.instance_variable_get(name)
25
+ value = progress[value.object_id] || value.full_dup(progress)
26
+ result.instance_variable_set(name, value)
27
+ end
28
+ end
23
29
  end
24
30
 
25
31
  result
@@ -7,14 +7,20 @@ class Struct
7
7
  progress[object_id] = result = dup
8
8
  exclude = full_dup_exclude
9
9
 
10
- members.each do |name|
11
-
12
- unless exclude.include?(name)
10
+ if exclude.empty?
11
+ members.each do |name|
13
12
  value = result[name]
14
13
  value = progress[value.object_id] || value.full_dup(progress)
15
14
  result[name] = value
16
15
  end
17
-
16
+ else
17
+ members.each do |name|
18
+ unless exclude.include?(name)
19
+ value = result[name]
20
+ value = progress[value.object_id] || value.full_dup(progress)
21
+ result[name] = value
22
+ end
23
+ end
18
24
  end
19
25
 
20
26
  result
@@ -0,0 +1,19 @@
1
+ # coding: utf-8
2
+
3
+ module FullDupDup
4
+ def full_dup(_progress=nil)
5
+ dup
6
+ end
7
+ end
8
+
9
+ class String
10
+ include FullDupDup
11
+ end
12
+
13
+ class Enumerator
14
+ include FullDupDup
15
+ end
16
+
17
+ class MatchData
18
+ include FullDupDup
19
+ end
@@ -0,0 +1,36 @@
1
+ # coding: utf-8
2
+
3
+ module FullDupSelf
4
+ def full_dup(_progress=nil)
5
+ self
6
+ end
7
+ end
8
+
9
+ class Numeric
10
+ include FullDupSelf
11
+ end
12
+
13
+ class NilClass
14
+ include FullDupSelf
15
+ end
16
+
17
+ class TrueClass
18
+ include FullDupSelf
19
+ end
20
+
21
+ class FalseClass
22
+ include FullDupSelf
23
+ end
24
+
25
+ class Symbol
26
+ include FullDupSelf
27
+ end
28
+
29
+ class Regexp
30
+ include FullDupSelf
31
+ end
32
+
33
+ class Thread
34
+ include FullDupSelf
35
+ end
36
+
@@ -1,5 +1,5 @@
1
1
  # coding: utf-8
2
2
 
3
3
  module FullDup
4
- VERSION = "0.0.5"
4
+ VERSION = "0.0.6"
5
5
  end
data/lib/full_dup.rb CHANGED
@@ -1,37 +1,12 @@
1
1
  # coding: utf-8
2
2
 
3
+ # A deep, safe, recursive variant of the dup method. The full_dup method.
4
+
5
+ require_relative 'full_dup/use_self'
6
+ require_relative 'full_dup/use_dup'
3
7
  require_relative 'full_dup/version'
4
8
  require_relative 'full_dup/object'
5
9
  require_relative 'full_dup/array'
6
10
  require_relative 'full_dup/hash'
7
11
  require_relative 'full_dup/struct'
8
12
 
9
- module FullDup
10
- def full_dup(_progress={})
11
- self
12
- end
13
- end
14
-
15
- class Numeric
16
- include FullDup
17
- end
18
-
19
- class NilClass
20
- include FullDup
21
- end
22
-
23
- class TrueClass
24
- include FullDup
25
- end
26
-
27
- class FalseClass
28
- include FullDup
29
- end
30
-
31
- class Symbol
32
- include FullDup
33
- end
34
-
35
- class Regexp
36
- include FullDup
37
- end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: full_dup
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Camilleri
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-02-13 00:00:00.000000000 Z
11
+ date: 2018-08-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -85,6 +85,8 @@ files:
85
85
  - lib/full_dup/hash.rb
86
86
  - lib/full_dup/object.rb
87
87
  - lib/full_dup/struct.rb
88
+ - lib/full_dup/use_dup.rb
89
+ - lib/full_dup/use_self.rb
88
90
  - lib/full_dup/version.rb
89
91
  - rakefile.rb
90
92
  homepage: https://github.com/PeterCamilleri/full_dup
@@ -107,9 +109,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
107
109
  version: '0'
108
110
  requirements: []
109
111
  rubyforge_project:
110
- rubygems_version: 2.2.3
112
+ rubygems_version: 2.5.2
111
113
  signing_key:
112
114
  specification_version: 4
113
115
  summary: A dup variant that performs a deep copy.
114
116
  test_files: []
115
- has_rdoc: