full_clone 0.0.9 → 1.0.3

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
- SHA1:
3
- metadata.gz: c5671e38cbd5b3f7214be72da4d3e5d183a41d7d
4
- data.tar.gz: 174f1e3f0e7279565e2843a88e59665df9c184b2
2
+ SHA256:
3
+ metadata.gz: 5c4bb3ef9f2dcd49d155858bcc4a198ee0e6c3410b49e406ba93f0185ebfac86
4
+ data.tar.gz: e81fefb70bb156809382a11018341ba30df8548e2d065b5bfe780f277285f213
5
5
  SHA512:
6
- metadata.gz: 6871aaf141f6c9c4c44cc9b3ab6fca0d56b39544a7fe7b0b87f96ea554d5ee8cd01636bf0dcd2d0c9bf2e67f5875ff4104d0f72887287ba73270d3d90fec8da0
7
- data.tar.gz: ee7830f9882649c34c2d063638fe08b0391855d11c732ca81010158d915841191ddbc08d9a4afe22e398af5909d6404c9a7b4dd765325247a582be7bee3cabe2
6
+ metadata.gz: 272c5e4919f5db8acb9a9c5b5f075df9a8ea161a7876ddb84de7d9bc17c96694b583efc917ee882133eddc95574de38f12cb9487d2d079d1dfb55a578c2eda32
7
+ data.tar.gz: abe36357abdf599f5d25408603175446d8e80a3bc5643816b62232a01109611aa175abe93d52ce02e0ebc065e2aca9b653907f46e9aa7777a6bdc46376f16d54
data/README.md CHANGED
@@ -6,6 +6,8 @@ cloned copy. The full_clone method digs deep and makes copies of these internal
6
6
  variables, not just arrays and hashes. It also allows classes to specify an
7
7
  exclusion list of variables that are not to be processed.
8
8
 
9
+ New for version 0.0.10, now 84% faster (at least full_dup was in my tests).
10
+
9
11
  This comprehensive approach creates another issue to be resolved. In Ruby, if an
10
12
  attempt is made to clone an immutable data item like a number, an error occurs.
11
13
  The justification for this uncharacteristic strictness is not at all clear, but
@@ -13,8 +15,9 @@ it does mean that the clone operation must be applied with great care.
13
15
 
14
16
  Unlike the standard clone method, the full\_clone method does not throw an
15
17
  exception when it sees un-clonable 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 cloned. Instead of having a fit, the code just works!
18
+ simply return themselves. This is deemed correct because those types of objects
19
+ are immutable and do not need to be duped. Instead of raising an exception, the
20
+ code returns the immutable object instead.
18
21
 
19
22
  Another issue that this gem deals with is that of data with looping reference
20
23
  chains. To handle this, the code tracks object ID values and does not re-clone
@@ -116,3 +119,14 @@ broken!
116
119
 
117
120
  Go to the GitHub repository and raise an issue calling attention to some
118
121
  aspect that could use some TLC or a suggestion or an idea.
122
+
123
+ ## License
124
+
125
+ The gem is available as open source under the terms of the
126
+ [MIT License](./LICENSE.txt).
127
+
128
+ ## Code of Conduct
129
+
130
+ Everyone interacting in the fully_freeze project’s codebases, issue trackers,
131
+ chat rooms and mailing lists is expected to follow the
132
+ [code of conduct](./CODE_OF_CONDUCT.md).
data/full_clone.gemspec CHANGED
@@ -17,9 +17,8 @@ Gem::Specification.new do |spec|
17
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
18
  spec.require_paths = ["lib"]
19
19
 
20
- spec.add_development_dependency "rake", "~> 12.0"
21
- spec.add_development_dependency "bundler", "~> 1.3"
20
+ spec.add_development_dependency "rake", ">= 12.3.3"
21
+ spec.add_development_dependency "bundler", ">= 2.1.0"
22
22
  spec.add_development_dependency 'minitest', "~> 5.7"
23
- spec.add_development_dependency 'minitest_visible', "~> 0.1"
24
-
23
+ spec.add_development_dependency 'reek', "~> 5.0.2"
25
24
  end
data/lib/full_clone.rb CHANGED
@@ -1,37 +1,11 @@
1
1
  # coding: utf-8
2
2
 
3
+ # A deep, safe, recursive variant of the clone method. The full_clone method.
4
+
5
+ require_relative 'full_clone/use_self'
6
+ require_relative 'full_clone/use_clone'
3
7
  require_relative 'full_clone/version'
4
8
  require_relative 'full_clone/object'
5
9
  require_relative 'full_clone/array'
6
10
  require_relative 'full_clone/hash'
7
11
  require_relative 'full_clone/struct'
8
-
9
- module FullClone
10
- def full_clone(_progress={})
11
- self
12
- end
13
- end
14
-
15
- class Numeric
16
- include FullClone
17
- end
18
-
19
- class NilClass
20
- include FullClone
21
- end
22
-
23
- class TrueClass
24
- include FullClone
25
- end
26
-
27
- class FalseClass
28
- include FullClone
29
- end
30
-
31
- class Symbol
32
- include FullClone
33
- end
34
-
35
- class Regexp
36
- include FullClone
37
- end
@@ -1,21 +1,26 @@
1
- class Array
1
+ # coding: utf-8
2
2
 
3
- #The full_clone method for arrays.
4
- def full_clone(progress={})
5
- progress[object_id] = result = clone
6
- exclude = full_clone_exclude
3
+ # Add full_clone support to all arrays.
4
+ class Array
7
5
 
6
+ # Do a full_clone with no exclusions
7
+ def full_clone_no_exclusions(progress)
8
8
  each_index do |name|
9
+ value = self[name]
10
+ value = progress[value.object_id] || value.full_clone(progress)
11
+ self[name] = value
12
+ end
13
+ end
9
14
 
15
+ # Do a full_clone with exclusions
16
+ def full_clone_with_exclusions(progress, exclude)
17
+ each_index do |name|
10
18
  unless exclude.include?(name)
11
- value = result[name]
19
+ value = self[name]
12
20
  value = progress[value.object_id] || value.full_clone(progress)
13
- result[name] = value
21
+ self[name] = value
14
22
  end
15
-
16
23
  end
17
-
18
- result
19
24
  end
20
25
 
21
26
  end
@@ -1,21 +1,26 @@
1
- class Hash
1
+ # coding: utf-8
2
2
 
3
- #The full_clone method for structs.
4
- def full_clone(progress={})
5
- progress[object_id] = result = clone
6
- exclude = full_clone_exclude
3
+ # Add full_clone support to all hashes.
4
+ class Hash
7
5
 
6
+ # Do a full_clone with no exclusions
7
+ def full_clone_no_exclusions(progress)
8
8
  each_key do |name|
9
+ value = self[name]
10
+ value = progress[value.object_id] || value.full_clone(progress)
11
+ self[name] = value
12
+ end
13
+ end
9
14
 
15
+ # Do a full_clone with exclusions
16
+ def full_clone_with_exclusions(progress, exclude)
17
+ each_key do |name|
10
18
  unless exclude.include?(name)
11
- value = result[name]
19
+ value = self[name]
12
20
  value = progress[value.object_id] || value.full_clone(progress)
13
- result[name] = value
21
+ self[name] = value
14
22
  end
15
-
16
23
  end
17
-
18
- result
19
24
  end
20
25
 
21
26
  end
@@ -1,3 +1,6 @@
1
+ # coding: utf-8
2
+
3
+ # Add full_clone support to all objects.
1
4
  class Object
2
5
 
3
6
  #By default, no instance variables are excluded.
@@ -5,22 +8,38 @@ class Object
5
8
  []
6
9
  end
7
10
 
8
- #The full_clone method for most objects.
11
+ #The common part of the full_clone method.
9
12
  def full_clone(progress={})
10
13
  progress[object_id] = result = clone
11
14
  exclude = full_clone_exclude
12
15
 
16
+ if exclude.empty?
17
+ result.full_clone_no_exclusions(progress)
18
+ else
19
+ result.full_clone_with_exclusions(progress, exclude)
20
+ end
21
+
22
+ result
23
+ end
24
+
25
+ # Do a full_clone with no exclusions
26
+ def full_clone_no_exclusions(progress)
13
27
  instance_variables.each do |name|
28
+ value = instance_variable_get(name)
29
+ value = progress[value.object_id] || value.full_clone(progress)
30
+ instance_variable_set(name, value)
31
+ end
32
+ end
14
33
 
34
+ # Do a full_clone with exclusions
35
+ def full_clone_with_exclusions(progress, exclude)
36
+ instance_variables.each do |name|
15
37
  unless exclude.include?(name)
16
- value = result.instance_variable_get(name)
38
+ value = instance_variable_get(name)
17
39
  value = progress[value.object_id] || value.full_clone(progress)
18
- result.instance_variable_set(name, value)
40
+ instance_variable_set(name, value)
19
41
  end
20
-
21
42
  end
22
-
23
- result
24
43
  end
25
44
 
26
45
  end
@@ -1,21 +1,26 @@
1
- class Struct
1
+ # coding: utf-8
2
2
 
3
- #The full_clone method for structs.
4
- def full_clone(progress={})
5
- progress[object_id] = result = clone
6
- exclude = full_clone_exclude
3
+ # Add full_clone support to the struct class.
4
+ class Struct
7
5
 
6
+ # Do a full_clone with no exclusions
7
+ def full_clone_no_exclusions(progress)
8
8
  members.each do |name|
9
+ value = self[name]
10
+ value = progress[value.object_id] || value.full_clone(progress)
11
+ self[name] = value
12
+ end
13
+ end
9
14
 
15
+ # Do a full_clone with exclusions
16
+ def full_clone_with_exclusions(progress, exclude)
17
+ members.each do |name|
10
18
  unless exclude.include?(name)
11
- value = result[name]
19
+ value = self[name]
12
20
  value = progress[value.object_id] || value.full_clone(progress)
13
- result[name] = value
21
+ self[name] = value
14
22
  end
15
-
16
23
  end
17
-
18
- result
19
24
  end
20
25
 
21
26
  end
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+
3
+ # A mixin for cloning use Ruby clone.
4
+ module FullCloneClone
5
+ def full_clone(_progress=nil)
6
+ clone
7
+ end
8
+ end
9
+
10
+ # String full clone support.
11
+ class String
12
+ include FullCloneClone
13
+ end
14
+
15
+ # Enumerator full clone support.
16
+ class Enumerator
17
+ include FullCloneClone
18
+ end
19
+
20
+ # Matchdata full clone support.
21
+ class MatchData
22
+ include FullCloneClone
23
+ end
@@ -0,0 +1,43 @@
1
+ # coding: utf-8
2
+
3
+ # A mixin for cloning as self.
4
+ module FullCloneSelf
5
+ def full_clone(_progress=nil)
6
+ self
7
+ end
8
+ end
9
+
10
+ # Numeric supports full clone.
11
+ class Numeric
12
+ include FullCloneSelf
13
+ end
14
+
15
+ # NilClass supports full clone.
16
+ class NilClass
17
+ include FullCloneSelf
18
+ end
19
+
20
+ # TrueClass supports full clone.
21
+ class TrueClass
22
+ include FullCloneSelf
23
+ end
24
+
25
+ # FalseClass supports full clone.
26
+ class FalseClass
27
+ include FullCloneSelf
28
+ end
29
+
30
+ # Symbols support full clone.
31
+ class Symbol
32
+ include FullCloneSelf
33
+ end
34
+
35
+ # Regular expressions support full clone.
36
+ class Regexp
37
+ include FullCloneSelf
38
+ end
39
+
40
+ # Threads support full clone.
41
+ class Thread
42
+ include FullCloneSelf
43
+ end
@@ -1,3 +1,3 @@
1
1
  module FullClone
2
- VERSION = "0.0.9"
2
+ VERSION = "1.0.3"
3
3
  end
data/rakefile.rb CHANGED
@@ -12,6 +12,11 @@ Rake::TestTask.new do |t|
12
12
  t.verbose = false
13
13
  end
14
14
 
15
+ desc "Run a scan for smelly code!"
16
+ task :reek do |t|
17
+ `reek --no-color lib > reek.txt`
18
+ end
19
+
15
20
  desc "Run an IRB Session with full_clone loaded."
16
21
  task :console do
17
22
  system "ruby irbt.rb local"
data/reek.txt ADDED
@@ -0,0 +1 @@
1
+ 0 total warnings
data/test/array_tests.rb CHANGED
@@ -3,14 +3,10 @@
3
3
  require_relative '../lib/full_clone'
4
4
  gem 'minitest'
5
5
  require 'minitest/autorun'
6
- require 'minitest_visible'
7
6
 
8
7
  #Test the monkey patches applied to the Object class.
9
8
  class ArrayFullCloneTester < Minitest::Test
10
9
 
11
- #Track mini-test progress.
12
- include MinitestVisible
13
-
14
10
  def test_basic_deep_cloning
15
11
  sa = "North"
16
12
  simple1 = [sa, 5, nil]
@@ -18,7 +14,7 @@ class ArrayFullCloneTester < Minitest::Test
18
14
 
19
15
  assert_equal(simple1[0], simple2[0])
20
16
  assert_equal(simple1[1], 5)
21
- assert_equal(simple1[2], nil)
17
+ assert_nil(simple1[2])
22
18
  refute_equal(simple1[0].object_id, simple2[0].object_id)
23
19
 
24
20
  sa << "West"
@@ -38,7 +34,7 @@ class ArrayFullCloneTester < Minitest::Test
38
34
 
39
35
  assert_equal(simple1[0], simple2[0])
40
36
  assert_equal(simple1[1], 5)
41
- assert_equal(simple1[2], nil)
37
+ assert_nil(simple1[2])
42
38
  assert_equal(simple1[0].object_id, simple2[0].object_id)
43
39
  end
44
40
 
@@ -3,14 +3,10 @@
3
3
  require_relative '../lib/full_clone'
4
4
  gem 'minitest'
5
5
  require 'minitest/autorun'
6
- require 'minitest_visible'
7
6
 
8
7
  #Test the monkey patches applied to the Object class.
9
8
  class FullCloneTester < Minitest::Test
10
9
 
11
- #Track mini-test progress.
12
- include MinitestVisible
13
-
14
10
  def test_for_safe_value_cloning
15
11
  assert_equal((6).full_clone, 6)
16
12
  assert_equal((6).full_clone.object_id, (6).object_id)
@@ -24,7 +20,7 @@ class FullCloneTester < Minitest::Test
24
20
  assert_equal((false).full_clone, false)
25
21
  assert_equal((false).full_clone.object_id, (false).object_id)
26
22
 
27
- assert_equal((nil).full_clone, nil)
23
+ assert_nil((nil).full_clone)
28
24
  assert_equal((nil).full_clone.object_id, (nil).object_id)
29
25
 
30
26
  rex = /ABC/
data/test/hash_tests.rb CHANGED
@@ -3,14 +3,10 @@
3
3
  require_relative '../lib/full_clone'
4
4
  gem 'minitest'
5
5
  require 'minitest/autorun'
6
- require 'minitest_visible'
7
6
 
8
7
  #Test the monkey patches applied to the Object class.
9
8
  class HashFullCloneTester < Minitest::Test
10
9
 
11
- #Track mini-test progress.
12
- include MinitestVisible
13
-
14
10
  def test_basic_deep_cloning
15
11
  sa = "North"
16
12
  simple1 = {iva: sa, ivb: 5, ivc: nil}
@@ -18,7 +14,7 @@ class HashFullCloneTester < Minitest::Test
18
14
 
19
15
  assert_equal(simple1[:iva], simple2[:iva])
20
16
  assert_equal(simple1[:ivb], 5)
21
- assert_equal(simple1[:ivc], nil)
17
+ assert_nil(simple1[:ivc])
22
18
  refute_equal(simple1[:iva].object_id, simple2[:iva].object_id)
23
19
 
24
20
  sa << "West"
@@ -38,7 +34,7 @@ class HashFullCloneTester < Minitest::Test
38
34
 
39
35
  assert_equal(simple1[:iva], simple2[:iva])
40
36
  assert_equal(simple1[:ivb], 5)
41
- assert_equal(simple1[:ivc], nil)
37
+ assert_nil(simple1[:ivc])
42
38
  assert_equal(simple1[:iva].object_id, simple2[:iva].object_id)
43
39
  end
44
40
 
data/test/object_tests.rb CHANGED
@@ -3,7 +3,6 @@
3
3
  require_relative '../lib/full_clone'
4
4
  gem 'minitest'
5
5
  require 'minitest/autorun'
6
- require 'minitest_visible'
7
6
 
8
7
  #Test the monkey patches applied to the Object class.
9
8
  class ObjectFullCloneTester < Minitest::Test
@@ -18,9 +17,6 @@ class ObjectFullCloneTester < Minitest::Test
18
17
  end
19
18
  end
20
19
 
21
- #Track mini-test progress.
22
- include MinitestVisible
23
-
24
20
  def test_basic_deep_cloning
25
21
  sa = "North"
26
22
  simple1 = SimpleClass.new(sa, 5, nil)
@@ -28,7 +24,7 @@ class ObjectFullCloneTester < Minitest::Test
28
24
 
29
25
  assert_equal(simple1.iva, simple2.iva)
30
26
  assert_equal(simple1.ivb, 5)
31
- assert_equal(simple1.ivc, nil)
27
+ assert_nil(simple1.ivc)
32
28
  refute_equal(simple1.iva.object_id, simple2.iva.object_id)
33
29
 
34
30
  sa << "West"
@@ -48,7 +44,7 @@ class ObjectFullCloneTester < Minitest::Test
48
44
 
49
45
  assert_equal(simple1.iva, simple2.iva)
50
46
  assert_equal(simple1.ivb, 5)
51
- assert_equal(simple1.ivc, nil)
47
+ assert_nil(simple1.ivc)
52
48
  assert_equal(simple1.iva.object_id, simple2.iva.object_id)
53
49
  end
54
50
 
data/test/struct_tests.rb CHANGED
@@ -3,16 +3,12 @@
3
3
  require_relative '../lib/full_clone'
4
4
  gem 'minitest'
5
5
  require 'minitest/autorun'
6
- require 'minitest_visible'
7
6
 
8
7
  #Test the monkey patches applied to the Object class.
9
8
  class StructFullCloneTester < Minitest::Test
10
9
 
11
10
  SimpleStruct = Struct.new(:iva, :ivb, :ivc)
12
11
 
13
- #Track mini-test progress.
14
- include MinitestVisible
15
-
16
12
  def test_basic_deep_cloning
17
13
  sa = "North"
18
14
  simple1 = SimpleStruct.new(sa, 5, nil)
@@ -20,7 +16,7 @@ class StructFullCloneTester < Minitest::Test
20
16
 
21
17
  assert_equal(simple1.iva, simple2.iva)
22
18
  assert_equal(simple1.ivb, 5)
23
- assert_equal(simple1.ivc, nil)
19
+ assert_nil(simple1.ivc)
24
20
  refute_equal(simple1.iva.object_id, simple2.iva.object_id)
25
21
 
26
22
  sa << "West"
@@ -40,7 +36,7 @@ class StructFullCloneTester < Minitest::Test
40
36
 
41
37
  assert_equal(simple1.iva, simple2.iva)
42
38
  assert_equal(simple1.ivb, 5)
43
- assert_equal(simple1.ivc, nil)
39
+ assert_nil(simple1.ivc)
44
40
  assert_equal(simple1.iva.object_id, simple2.iva.object_id)
45
41
  end
46
42
 
metadata CHANGED
@@ -1,43 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: full_clone
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 1.0.3
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: 2021-05-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '12.0'
19
+ version: 12.3.3
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '12.0'
26
+ version: 12.3.3
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '1.3'
33
+ version: 2.1.0
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '1.3'
40
+ version: 2.1.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: minitest
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -53,19 +53,19 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '5.7'
55
55
  - !ruby/object:Gem::Dependency
56
- name: minitest_visible
56
+ name: reek
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0.1'
61
+ version: 5.0.2
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '0.1'
68
+ version: 5.0.2
69
69
  description: A (safe/no exceptions) clone variant that performs a deep, recursive
70
70
  copy.
71
71
  email:
@@ -86,8 +86,11 @@ files:
86
86
  - lib/full_clone/hash.rb
87
87
  - lib/full_clone/object.rb
88
88
  - lib/full_clone/struct.rb
89
+ - lib/full_clone/use_clone.rb
90
+ - lib/full_clone/use_self.rb
89
91
  - lib/full_clone/version.rb
90
92
  - rakefile.rb
93
+ - reek.txt
91
94
  - test/array_tests.rb
92
95
  - test/deep_clone_tests.rb
93
96
  - test/hash_tests.rb
@@ -112,8 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
112
115
  - !ruby/object:Gem::Version
113
116
  version: '0'
114
117
  requirements: []
115
- rubyforge_project:
116
- rubygems_version: 2.2.3
118
+ rubygems_version: 3.2.17
117
119
  signing_key:
118
120
  specification_version: 4
119
121
  summary: A clone variant that performs a deep copy.
@@ -123,4 +125,3 @@ test_files:
123
125
  - test/hash_tests.rb
124
126
  - test/object_tests.rb
125
127
  - test/struct_tests.rb
126
- has_rdoc: