safe_dup 0.0.1 → 0.0.2
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 +4 -4
- data/README.md +46 -46
- data/bench/bench.rb +26 -0
- data/lib/safe_dup/version.rb +1 -1
- data/safe_dup.gemspec +2 -2
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cf5c446b84f98473efdc4be779f14f01cbb39c54
|
4
|
+
data.tar.gz: bcdeb89a7674518782642ed1a89c744bf7063782
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8ed82120fb15e78532bd33d0be142e0efe6a203d8142ad0b54ccd6e89fde735dd5fa29c58c298fc4d5fad9a38880b1a451628efe7f25f7a99ff76f9256e57127
|
7
|
+
data.tar.gz: 091a6a95d5073f772ab074c9878d5047acb48573b84a069c1d391661b5baa46f4d3373633575812bd488731dc3c47705d9799abff47fddd0eca122c96f4fca3d
|
data/README.md
CHANGED
@@ -1,20 +1,20 @@
|
|
1
1
|
# SafeDup
|
2
2
|
|
3
|
-
This tiny gem implements a version of
|
4
|
-
attempt is made to
|
3
|
+
This tiny gem implements a version of dup called safe_dup. In Ruby, if an
|
4
|
+
attempt is made to dup an immutable data item like a number, an error occurs.
|
5
5
|
The justification for this uncharacteristic strictness is not at all clear, but
|
6
|
-
it does mean that the
|
6
|
+
it does mean that the dup operation must be applied with great care.
|
7
7
|
|
8
|
-
Unlike the standard
|
8
|
+
Unlike the standard dup method, the safe\_dup method does not throw an
|
9
9
|
exception when sent to un-clonable value objects like 42 or true. These values
|
10
10
|
simply return themselves. This is correct because those types of objects do
|
11
|
-
not _need_ to be
|
11
|
+
not _need_ to be dupd. Instead of having a fit, the code just works!
|
12
12
|
|
13
13
|
On a note about performance, this gem does not just rescue the exceptions
|
14
|
-
normally generated by
|
14
|
+
normally generated by dup, it prevents them from occurring and wasting time
|
15
15
|
in the first place.
|
16
16
|
|
17
|
-
Finally, this gem does not monkey patch the behavior of the
|
17
|
+
Finally, this gem does not monkey patch the behavior of the dup method.
|
18
18
|
Modifying such a crucial method was considered too risky. Instead, the
|
19
19
|
safe_dup method is introduced. This is done to reduce the possibility of
|
20
20
|
breaking existing code that often occurs when monkey patching goes too far.
|
@@ -37,26 +37,26 @@ Or install it yourself as:
|
|
37
37
|
|
38
38
|
require 'safe_dup'
|
39
39
|
|
40
|
-
then, in those places where regular
|
40
|
+
then, in those places where regular dup was problematic, use:
|
41
41
|
|
42
42
|
foo = my_object.safe_dup
|
43
43
|
|
44
44
|
instead of
|
45
45
|
|
46
46
|
begin
|
47
|
-
foo = my_object.
|
47
|
+
foo = my_object.dup
|
48
48
|
rescue TypeError
|
49
49
|
foo = my_object
|
50
50
|
end
|
51
51
|
|
52
|
-
It is actually pretty easy to determine where
|
53
|
-
those places where the
|
52
|
+
It is actually pretty easy to determine where safe_dup needs to be used. It's
|
53
|
+
those places where the dup method is generating unwanted exceptions.
|
54
54
|
|
55
55
|
## Performance
|
56
|
-
A reasonable question to raise is "How does safe
|
56
|
+
A reasonable question to raise is "How does safe\_dup compare with just
|
57
57
|
catching the exception and handling it?" The benchmark sets a a realistic
|
58
58
|
scenario where an array (whose contents may be varied) is having its
|
59
|
-
_contents_
|
59
|
+
_contents_ duplicated. The benchmarking code follows:
|
60
60
|
|
61
61
|
```ruby
|
62
62
|
require "benchmark/ips"
|
@@ -81,8 +81,8 @@ end
|
|
81
81
|
X = ["Test", :test, 43, true, nil, false]
|
82
82
|
|
83
83
|
Benchmark.ips do |x|
|
84
|
-
x.report("
|
85
|
-
x.report("
|
84
|
+
x.report("Dup with standard dup method") { X.use_dup }
|
85
|
+
x.report("Dup with the safe dup method") { X.use_safe_dup }
|
86
86
|
x.compare!
|
87
87
|
end
|
88
88
|
```
|
@@ -90,54 +90,54 @@ end
|
|
90
90
|
#### Results: ruby 1.9.3p484 (2013-11-22) [i386-mingw32]
|
91
91
|
C:\Sites\safe_dup>ruby bench\bench.rb
|
92
92
|
Warming up --------------------------------------
|
93
|
-
|
94
|
-
1.
|
95
|
-
|
96
|
-
|
93
|
+
Dup with standard dup method
|
94
|
+
1.245k i/100ms
|
95
|
+
Dup with the safe dup method
|
96
|
+
34.118k i/100ms
|
97
97
|
Calculating -------------------------------------
|
98
|
-
|
99
|
-
12.
|
100
|
-
|
101
|
-
|
98
|
+
Dup with standard dup method
|
99
|
+
12.862k (± 6.2%) i/s - 64.740k
|
100
|
+
Dup with the safe dup method
|
101
|
+
533.927k (± 6.5%) i/s - 2.661M
|
102
102
|
|
103
103
|
Comparison:
|
104
|
-
|
105
|
-
|
104
|
+
Dup with the safe dup method: 533926.5 i/s
|
105
|
+
Dup with standard dup method: 12861.7 i/s - 41.51x slower
|
106
106
|
|
107
107
|
#### Results: ruby 2.1.6p336 (2015-04-13 revision 50298) [i386-mingw32]
|
108
108
|
C:\Sites\safe_dup>ruby bench\bench.rb
|
109
109
|
Warming up --------------------------------------
|
110
|
-
|
111
|
-
4.
|
112
|
-
|
113
|
-
38.
|
110
|
+
Dup with standard dup method
|
111
|
+
4.969k i/100ms
|
112
|
+
Dup with the safe dup method
|
113
|
+
38.025k i/100ms
|
114
114
|
Calculating -------------------------------------
|
115
|
-
|
116
|
-
54.
|
117
|
-
|
118
|
-
|
115
|
+
Dup with standard dup method
|
116
|
+
54.786k (± 7.1%) i/s - 273.295k
|
117
|
+
Dup with the safe dup method
|
118
|
+
567.814k (±10.1%) i/s - 2.814M
|
119
119
|
|
120
120
|
Comparison:
|
121
|
-
|
122
|
-
|
121
|
+
Dup with the safe dup method: 567814.3 i/s
|
122
|
+
Dup with standard dup method: 54785.8 i/s - 10.36x slower
|
123
123
|
|
124
124
|
#### Results: ruby 2.2.3p173 (2015-08-18 revision 51636) [i386-cygwin]
|
125
|
-
Peter Camilleri@NCC1701G /cygdrive/c/sites/safe_dup
|
126
125
|
$ ruby bench/bench.rb
|
127
126
|
Warming up --------------------------------------
|
128
|
-
|
129
|
-
3.
|
130
|
-
|
131
|
-
28.
|
127
|
+
Dup with standard dup method
|
128
|
+
3.662k i/100ms
|
129
|
+
Dup with the safe dup method
|
130
|
+
28.310k i/100ms
|
132
131
|
Calculating -------------------------------------
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
132
|
+
Dup with standard dup method
|
133
|
+
39.437k (± 6.1%) i/s - 197.748k
|
134
|
+
Dup with the safe dup method
|
135
|
+
450.558k (± 3.9%) i/s - 2.265M
|
137
136
|
|
138
137
|
Comparison:
|
139
|
-
|
140
|
-
|
138
|
+
Dup with the safe dup method: 450557.6 i/s
|
139
|
+
Dup with standard dup method: 39436.6 i/s - 11.42x slower
|
140
|
+
|
141
141
|
|
142
142
|
|
143
143
|
Overall: Shorter code _and_ faster. Winner, winner, chicken dinner!
|
data/bench/bench.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require "benchmark/ips"
|
2
|
+
require 'safe_dup'
|
3
|
+
|
4
|
+
class Array
|
5
|
+
def use_dup
|
6
|
+
self.map do |element|
|
7
|
+
begin
|
8
|
+
element.dup
|
9
|
+
rescue TypeError
|
10
|
+
element
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def use_safe_dup
|
16
|
+
self.map {|element| element.safe_dup }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
X = ["Test", :test, 43, true, nil, false]
|
21
|
+
|
22
|
+
Benchmark.ips do |x|
|
23
|
+
x.report("Dup with standard clone method") { X.use_dup }
|
24
|
+
x.report("Dup with the safe clone method") { X.use_safe_dup }
|
25
|
+
x.compare!
|
26
|
+
end
|
data/lib/safe_dup/version.rb
CHANGED
data/safe_dup.gemspec
CHANGED
@@ -9,8 +9,8 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["Peter Camilleri"]
|
10
10
|
spec.email = ["peter.c.camilleri@gmail.com"]
|
11
11
|
|
12
|
-
spec.
|
13
|
-
spec.
|
12
|
+
spec.description = "A safer version of the dup method that avoids unnecessary exceptions."
|
13
|
+
spec.summary = "A safer version of the dup method."
|
14
14
|
spec.homepage = "http://teuthida-technologies.com/"
|
15
15
|
spec.license = "MIT"
|
16
16
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: safe_dup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Camilleri
|
@@ -66,7 +66,7 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '5'
|
69
|
-
description: A safer version of the
|
69
|
+
description: A safer version of the dup method that avoids unnecessary exceptions.
|
70
70
|
email:
|
71
71
|
- peter.c.camilleri@gmail.com
|
72
72
|
executables: []
|
@@ -78,6 +78,7 @@ files:
|
|
78
78
|
- LICENSE.txt
|
79
79
|
- README.md
|
80
80
|
- Rakefile
|
81
|
+
- bench/bench.rb
|
81
82
|
- lib/safe_dup.rb
|
82
83
|
- lib/safe_dup/version.rb
|
83
84
|
- safe_dup.gemspec
|
@@ -105,7 +106,7 @@ rubyforge_project:
|
|
105
106
|
rubygems_version: 2.2.2
|
106
107
|
signing_key:
|
107
108
|
specification_version: 4
|
108
|
-
summary: A safer version of the dup method
|
109
|
+
summary: A safer version of the dup method.
|
109
110
|
test_files:
|
110
111
|
- test/safe_dup_tests.rb
|
111
112
|
has_rdoc:
|