safe_clone 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -13
- data/README.md +78 -6
- data/bench/bench.rb +22 -0
- data/lib/safe_clone/version.rb +1 -1
- data/lib/safe_clone.rb +12 -31
- data/safe_clone.gemspec +3 -2
- data/test/safe_clone_tests.rb +5 -13
- metadata +29 -14
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
NTE2OTc1ZjViZmM2YzhiMDcwNzRlZjcyMTlhYjllZjRhODgxMjE4ZQ==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c270e1501f513581f54e24e995dac45a3674108b
|
4
|
+
data.tar.gz: a0e903a567fb2cea836e8a9813dfed29a6004b34
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
ZjgzYzYwODcxMGE3OWM4OTdmMjE4NGJmZDFhNmRhZGJhYzRmYmYyYzA5ZWUz
|
11
|
-
Yjk1ZjliMTYyZDA3NGIzYjBkMDA4MTZlOGYwZGMzODA2NjBlOTg=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
NDczYjU3MWMwNjA0MmQ3Njk3Y2U2MjA1MjYzN2E3NjYyYjRlYmI5ZTIwZmE3
|
14
|
-
MTk2N2MxZjg1NGEwYWYyZmY2YjIyNGJlOWQyMDJiMmM0MjBiMTc2ZTU1NTFi
|
15
|
-
MTAwM2ZhMzA3ODNhNjIxMGM1NTliNDYxZTZmYmNhMDUwYjRlZmI=
|
6
|
+
metadata.gz: 57187deeb43c0dcc62f6cc503a596445e834aae18d3d378ac15a927e1f88a2cb58282d91a472597327c78eb81b744b3d4b29b728a354ac849d01d794c2e527e6
|
7
|
+
data.tar.gz: 61af8a6ea50fb4bbe924ca3e0e45a54a6802c2eae32b36cc666db9389d450777769414ef0f7b3728e9f67ac36aad305c89d5a636ab2c573f5c962fe806ea2b5b
|
data/README.md
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# SafeClone
|
2
2
|
|
3
|
-
This tiny gem implements a version of clone called
|
4
|
-
standard clone method, the
|
5
|
-
when sent to un-clonable objects like 42 or true. These simply
|
6
|
-
themselves
|
7
|
-
to be cloned. Instead of
|
3
|
+
This tiny gem implements a version of clone called safe\_clone. Unlike the
|
4
|
+
standard clone method, the safe\_clone method does not throw an exception
|
5
|
+
when sent to un-clonable value objects like 42 or true. These values simply
|
6
|
+
return themselves. This is correct because those types of objects do not _need_
|
7
|
+
to be cloned. Instead of having a fit, the code just works!
|
8
8
|
|
9
9
|
## Installation
|
10
10
|
|
@@ -30,8 +30,80 @@ then, in those places where regular clone was problematic, use:
|
|
30
30
|
|
31
31
|
instead of
|
32
32
|
|
33
|
-
|
33
|
+
begin
|
34
|
+
foo = my_object.clone
|
35
|
+
rescue TypeError
|
36
|
+
foo = my_object
|
37
|
+
end
|
34
38
|
|
39
|
+
Further, when benchmarked under
|
40
|
+
|
41
|
+
ruby 1.9.3p484 (2013-11-22) [i386-mingw32]
|
42
|
+
|
43
|
+
the following results are observed:
|
44
|
+
|
45
|
+
C:\Sites\safe_clone>ruby bench\bench.rb
|
46
|
+
Warming up --------------------------------------
|
47
|
+
Clone with standard clone method
|
48
|
+
6.424k i/100ms
|
49
|
+
Clone with the safe clone method
|
50
|
+
97.476k i/100ms
|
51
|
+
Calculating -------------------------------------
|
52
|
+
Clone with standard clone method
|
53
|
+
72.460k (± 8.5%) i/s - 366.168k
|
54
|
+
Clone with the safe clone method
|
55
|
+
4.690M (±33.3%) i/s - 20.957M
|
56
|
+
|
57
|
+
Comparison:
|
58
|
+
Clone with the safe clone method: 4690305.8 i/s
|
59
|
+
Clone with standard clone method: 72460.2 i/s - 64.73x slower
|
60
|
+
|
61
|
+
With:
|
62
|
+
|
63
|
+
ruby 2.1.6p336 (2015-04-13 revision 50298) [i386-mingw32]
|
64
|
+
|
65
|
+
the following results are observed:
|
66
|
+
|
67
|
+
C:\Sites\safe_clone>ruby bench\bench.rb
|
68
|
+
Warming up --------------------------------------
|
69
|
+
Clone with standard clone method
|
70
|
+
20.607k i/100ms
|
71
|
+
Clone with the safe clone method
|
72
|
+
107.236k i/100ms
|
73
|
+
Calculating -------------------------------------
|
74
|
+
Clone with standard clone method
|
75
|
+
298.041k (±11.1%) i/s - 1.484M
|
76
|
+
Clone with the safe clone method
|
77
|
+
4.934M (±34.5%) i/s - 22.091M
|
78
|
+
|
79
|
+
Comparison:
|
80
|
+
Clone with the safe clone method: 4933871.9 i/s
|
81
|
+
Clone with standard clone method: 298041.4 i/s - 16.55x slower
|
82
|
+
|
83
|
+
And with:
|
84
|
+
|
85
|
+
ruby 2.2.3p173 (2015-08-18 revision 51636) [i386-cygwin]
|
86
|
+
|
87
|
+
we get:
|
88
|
+
|
89
|
+
$ ruby bench/bench.rb
|
90
|
+
Warming up --------------------------------------
|
91
|
+
Clone with standard clone method
|
92
|
+
15.876k i/100ms
|
93
|
+
Clone with the safe clone method
|
94
|
+
70.638k i/100ms
|
95
|
+
Calculating -------------------------------------
|
96
|
+
Clone with standard clone method
|
97
|
+
219.593k (±10.7%) i/s - 1.095M
|
98
|
+
Clone with the safe clone method
|
99
|
+
4.525M (± 0.9%) i/s - 22.675M
|
100
|
+
|
101
|
+
Comparison:
|
102
|
+
Clone with the safe clone method: 4524862.8 i/s
|
103
|
+
Clone with standard clone method: 219593.0 i/s - 20.61x slower
|
104
|
+
|
105
|
+
|
106
|
+
Overall: Shorter code _and_ faster. Winner, winner, chicken dinner!
|
35
107
|
|
36
108
|
## Contributing
|
37
109
|
|
data/bench/bench.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require "benchmark/ips"
|
2
|
+
require 'safe_clone'
|
3
|
+
|
4
|
+
def use_clone
|
5
|
+
x = 42
|
6
|
+
y = begin
|
7
|
+
x.clone
|
8
|
+
rescue
|
9
|
+
x
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def use_safe_clone
|
14
|
+
x = 42
|
15
|
+
y = x.safe_clone
|
16
|
+
end
|
17
|
+
|
18
|
+
Benchmark.ips do |x|
|
19
|
+
x.report("Clone with standard clone method") { use_clone }
|
20
|
+
x.report("Clone with the safe clone method") { use_safe_clone }
|
21
|
+
x.compare!
|
22
|
+
end
|
data/lib/safe_clone/version.rb
CHANGED
data/lib/safe_clone.rb
CHANGED
@@ -1,38 +1,19 @@
|
|
1
1
|
require "safe_clone/version"
|
2
2
|
|
3
|
-
module SafeClone
|
4
|
-
def safe_clone
|
5
|
-
self
|
6
|
-
end
|
7
|
-
end
|
8
|
-
|
9
3
|
class Object
|
10
|
-
|
11
|
-
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
class Numeric
|
16
|
-
include SafeClone
|
17
|
-
end
|
18
|
-
|
19
|
-
class NilClass
|
20
|
-
include SafeClone
|
4
|
+
#By default, reference types use the clone method.
|
5
|
+
def safe_clone; self.clone; end
|
21
6
|
end
|
22
7
|
|
23
|
-
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
class FalseClass
|
28
|
-
include SafeClone
|
29
|
-
end
|
30
|
-
|
31
|
-
class Symbol
|
32
|
-
include SafeClone
|
33
|
-
end
|
34
|
-
|
35
|
-
class Regexp
|
36
|
-
include SafeClone
|
8
|
+
#For value types, just return self!
|
9
|
+
module SafeClone
|
10
|
+
def safe_clone; self; end
|
37
11
|
end
|
38
12
|
|
13
|
+
#Update the Ruby value types.
|
14
|
+
class Numeric; include SafeClone; end
|
15
|
+
class NilClass; include SafeClone; end
|
16
|
+
class TrueClass; include SafeClone; end
|
17
|
+
class FalseClass; include SafeClone; end
|
18
|
+
class Symbol; include SafeClone; end
|
19
|
+
class Regexp; include SafeClone; end
|
data/safe_clone.gemspec
CHANGED
@@ -14,12 +14,13 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
17
|
-
# spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
17
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
18
|
spec.require_paths = ["lib"]
|
20
19
|
|
20
|
+
spec.add_development_dependency 'minitest_visible', ">= 0.0.2"
|
21
|
+
|
21
22
|
spec.add_development_dependency "bundler", "~> 1.3"
|
22
23
|
spec.add_development_dependency "rake"
|
23
|
-
spec.add_development_dependency 'minitest', "~>
|
24
|
+
spec.add_development_dependency 'minitest', "~> 5"
|
24
25
|
|
25
26
|
end
|
data/test/safe_clone_tests.rb
CHANGED
@@ -1,23 +1,15 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
3
|
require_relative '../lib/safe_clone'
|
4
|
+
gem 'minitest'
|
4
5
|
require 'minitest/autorun'
|
6
|
+
require 'minitest_visible'
|
5
7
|
|
6
8
|
#Test the monkey patches applied to the Object class.
|
7
|
-
class SafeCloneTester <
|
9
|
+
class SafeCloneTester < Minitest::Test
|
8
10
|
|
9
|
-
#
|
10
|
-
|
11
|
-
$do_this_only_one_time = "" unless defined? $do_this_only_one_time
|
12
|
-
|
13
|
-
if $do_this_only_one_time != __FILE__
|
14
|
-
puts
|
15
|
-
puts "Running test file: #{File.split(__FILE__)[1]}"
|
16
|
-
$do_this_only_one_time = __FILE__
|
17
|
-
end
|
18
|
-
|
19
|
-
super(*all)
|
20
|
-
end
|
11
|
+
#Track mini-test progress.
|
12
|
+
MinitestVisible.track self, __FILE__
|
21
13
|
|
22
14
|
def test_for_safe_value_cloning
|
23
15
|
assert_equal((6).safe_clone, 6)
|
metadata
CHANGED
@@ -1,57 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: safe_clone
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.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:
|
11
|
+
date: 2016-02-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: minitest_visible
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.0.2
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.0.2
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bundler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
16
30
|
requirements:
|
17
|
-
- - ~>
|
31
|
+
- - "~>"
|
18
32
|
- !ruby/object:Gem::Version
|
19
33
|
version: '1.3'
|
20
34
|
type: :development
|
21
35
|
prerelease: false
|
22
36
|
version_requirements: !ruby/object:Gem::Requirement
|
23
37
|
requirements:
|
24
|
-
- - ~>
|
38
|
+
- - "~>"
|
25
39
|
- !ruby/object:Gem::Version
|
26
40
|
version: '1.3'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: rake
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
30
44
|
requirements:
|
31
|
-
- -
|
45
|
+
- - ">="
|
32
46
|
- !ruby/object:Gem::Version
|
33
47
|
version: '0'
|
34
48
|
type: :development
|
35
49
|
prerelease: false
|
36
50
|
version_requirements: !ruby/object:Gem::Requirement
|
37
51
|
requirements:
|
38
|
-
- -
|
52
|
+
- - ">="
|
39
53
|
- !ruby/object:Gem::Version
|
40
54
|
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: minitest
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
|
-
- - ~>
|
59
|
+
- - "~>"
|
46
60
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
61
|
+
version: '5'
|
48
62
|
type: :development
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
|
-
- - ~>
|
66
|
+
- - "~>"
|
53
67
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
68
|
+
version: '5'
|
55
69
|
description: A safer version of the clone method that avoids unnecessary exceptions.
|
56
70
|
email:
|
57
71
|
- peter.c.camilleri@gmail.com
|
@@ -59,11 +73,12 @@ executables: []
|
|
59
73
|
extensions: []
|
60
74
|
extra_rdoc_files: []
|
61
75
|
files:
|
62
|
-
- .gitignore
|
76
|
+
- ".gitignore"
|
63
77
|
- Gemfile
|
64
78
|
- LICENSE.txt
|
65
79
|
- README.md
|
66
80
|
- Rakefile
|
81
|
+
- bench/bench.rb
|
67
82
|
- lib/safe_clone.rb
|
68
83
|
- lib/safe_clone/version.rb
|
69
84
|
- safe_clone.gemspec
|
@@ -78,17 +93,17 @@ require_paths:
|
|
78
93
|
- lib
|
79
94
|
required_ruby_version: !ruby/object:Gem::Requirement
|
80
95
|
requirements:
|
81
|
-
- -
|
96
|
+
- - ">="
|
82
97
|
- !ruby/object:Gem::Version
|
83
98
|
version: '0'
|
84
99
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
100
|
requirements:
|
86
|
-
- -
|
101
|
+
- - ">="
|
87
102
|
- !ruby/object:Gem::Version
|
88
103
|
version: '0'
|
89
104
|
requirements: []
|
90
105
|
rubyforge_project:
|
91
|
-
rubygems_version: 2.
|
106
|
+
rubygems_version: 2.2.2
|
92
107
|
signing_key:
|
93
108
|
specification_version: 4
|
94
109
|
summary: A safer version of the clone method.
|