in_array 0.1.3 → 0.1.4
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/.gitignore +2 -0
- data/README.md +127 -11
- data/bench/complex_bench.rb +52 -0
- data/bench/simple_bench.rb +31 -0
- data/lib/in_array/version.rb +1 -1
- metadata +4 -3
- data/Gemfile.lock +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1a8e4f410010aceefc1816040c2b3b54a8bcd8b6
|
4
|
+
data.tar.gz: 49119bd6a51e2db2e9a51bf517939c0d10659dc7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 884f59125deddec82a8d302cfd608b75264c6c17e69432b2b79ee9a54d004d00a699e55ef220d156dc208e6726df6e0a8caee3c898120cae594b22d09a2bd6d4
|
7
|
+
data.tar.gz: 243cf3a7acbcb93d451951c3057a0eaa6be59ad34de0117257def81e4bf39499360db155f74b381b337bfe5b1629f38237352f8f8a19e5b66eacb6c307ee567e
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -3,24 +3,140 @@
|
|
3
3
|
This project contains the Ruby in_array gem. This is perhaps the tiniest gem
|
4
4
|
ever created. It allows all objects to respond to the :in_array method that
|
5
5
|
encapsulates the object in an array unless it is already an array. So
|
6
|
+
```ruby
|
7
|
+
'Hello'.in_array # ['Hello']
|
8
|
+
['Hello'].in_array # ['Hello']
|
9
|
+
my_object.in_array # [my_object]
|
10
|
+
[1,2,3].in_array # [1,2,3]
|
11
|
+
```
|
12
|
+
This very simple gem accomplishes a very simple task that is nonetheless useful.
|
13
|
+
For example a method can now easily accept a single object or an array of
|
14
|
+
objects:
|
6
15
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
16
|
+
```ruby
|
17
|
+
def my_method(args, other)
|
18
|
+
args.in_array.each{|arg| process(arg, other) }
|
19
|
+
end
|
20
|
+
```
|
21
|
+
Now all of the following will work correctly:
|
22
|
+
```ruby
|
23
|
+
my_method 12, 11
|
24
|
+
my_method 42, 11
|
25
|
+
my_method [12, 42], 11
|
26
|
+
```
|
27
|
+
From an instructive view point, this gem also demonstrates the use of
|
28
|
+
inheritance as opposed to simulated polymorphism.
|
11
29
|
|
12
|
-
|
13
|
-
and true as opposed to simulated polymorphism.
|
30
|
+
## Installation
|
14
31
|
|
15
|
-
|
32
|
+
Add this line to your application's Gemfile:
|
16
33
|
|
17
|
-
|
34
|
+
gem 'in_array'
|
18
35
|
|
19
|
-
then
|
36
|
+
And then execute:
|
20
37
|
|
21
|
-
|
38
|
+
$ bundle
|
22
39
|
|
23
|
-
|
40
|
+
Or install it yourself as:
|
41
|
+
|
42
|
+
$ gem install in_array
|
43
|
+
|
44
|
+
|
45
|
+
## Usage
|
46
|
+
This is as simple as:
|
47
|
+
```ruby
|
48
|
+
require 'in_array'
|
49
|
+
```
|
24
50
|
|
51
|
+
then, in those places where array-ness was problematic, use:
|
52
|
+
```ruby
|
53
|
+
my_object.in_array.each do |option| #etc, etc, etc...
|
54
|
+
```
|
55
|
+
|
56
|
+
instead of
|
57
|
+
```ruby
|
25
58
|
my_object = [my_object] unless my_object.is_a?(Array)
|
26
59
|
my_object.each do |option| #etc, etc, etc...
|
60
|
+
```
|
61
|
+
|
62
|
+
#### Extending the Protocol
|
63
|
+
|
64
|
+
The in_array gem sets up a simple protocol that permits its behavior to be
|
65
|
+
easily added to user defined classes that behave (aka duck type) as arrays. The
|
66
|
+
following snippet shows how this is done:
|
67
|
+
```ruby
|
68
|
+
class MyArray
|
69
|
+
#This class behaves like an array.
|
70
|
+
include InArrayAlready
|
71
|
+
|
72
|
+
#Rest of the class omitted.
|
73
|
+
end
|
74
|
+
|
75
|
+
```
|
76
|
+
|
77
|
+
## Performance
|
78
|
+
|
79
|
+
All other aspects aside, good code should not exact a significant speed
|
80
|
+
penalty. The benchmark tests that follow show that the in_array gem should be
|
81
|
+
expected to improve performance when compared with the simulated polymorphism
|
82
|
+
alternative.
|
83
|
+
|
84
|
+
The first test assumes a simple scenario with only the Array class. Polymorphism
|
85
|
+
is simulated using the is_a? method:
|
86
|
+
|
87
|
+
C:\Sites\in_array>ruby bench\simple_bench.rb
|
88
|
+
Warming up --------------------------------------
|
89
|
+
Process with in_array
|
90
|
+
5.178k i/100ms
|
91
|
+
Process with is_a?
|
92
|
+
4.037k i/100ms
|
93
|
+
Calculating -------------------------------------
|
94
|
+
Process with in_array
|
95
|
+
54.001k (± 5.4%) i/s - 274.434k
|
96
|
+
Process with is_a?
|
97
|
+
41.897k (± 5.3%) i/s - 209.924k
|
98
|
+
|
99
|
+
Comparison:
|
100
|
+
Process with in_array: 54000.9 i/s
|
101
|
+
Process with is_a? : 41897.1 i/s - 1.29x slower
|
102
|
+
|
103
|
+
The second scenario adds a user defined array like class. In this case, two
|
104
|
+
methods of simulated polymorphism are tested, based on include? and a hash
|
105
|
+
of allowed array classes. Here are those results.
|
106
|
+
|
107
|
+
C:\Sites\in_array>ruby bench\complex_bench.rb
|
108
|
+
Warming up --------------------------------------
|
109
|
+
Process with in_array
|
110
|
+
5.163k i/100ms
|
111
|
+
Process with hash[]
|
112
|
+
1.779k i/100ms
|
113
|
+
Process with include?
|
114
|
+
1.895k i/100ms
|
115
|
+
Calculating -------------------------------------
|
116
|
+
Process with in_array
|
117
|
+
54.239k (± 5.3%) i/s - 273.639k
|
118
|
+
Process with hash[]
|
119
|
+
17.924k (± 3.2%) i/s - 90.729k
|
120
|
+
Process with include?
|
121
|
+
19.232k (± 3.8%) i/s - 96.645k
|
122
|
+
|
123
|
+
Comparison:
|
124
|
+
Process with in_array: 54238.6 i/s
|
125
|
+
Process with include?: 19231.7 i/s - 2.82x slower
|
126
|
+
Process with hash[] : 17923.9 i/s - 3.03x slower
|
127
|
+
|
128
|
+
## Contributing
|
129
|
+
|
130
|
+
#### Plan A
|
131
|
+
|
132
|
+
1. Fork it ( https://github.com/PeterCamilleri/in_array/fork )
|
133
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
134
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
135
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
136
|
+
5. Create a new Pull Request
|
137
|
+
|
138
|
+
#### Plan B
|
139
|
+
|
140
|
+
Go to the GitHub repository and raise an issue calling attention to some
|
141
|
+
aspect that could use some TLC or a suggestion or an idea.
|
142
|
+
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require "benchmark/ips"
|
2
|
+
require 'in_array'
|
3
|
+
|
4
|
+
class MyArray
|
5
|
+
#Pretend that this class behaves like an array.
|
6
|
+
include InArrayAlready
|
7
|
+
end
|
8
|
+
|
9
|
+
class Object
|
10
|
+
def slow_in_array
|
11
|
+
if [Array, MyArray].include? self.class
|
12
|
+
self
|
13
|
+
else
|
14
|
+
[ self ]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
ARRAY_CLUB = {Array => true, MyArray => true }
|
19
|
+
|
20
|
+
def accel_in_array
|
21
|
+
if ARRAY_CLUB[self.class]
|
22
|
+
self
|
23
|
+
else
|
24
|
+
[ self ]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
Test1 = (1..100).to_a
|
30
|
+
Test2 = Array(100) { MyArray.new }
|
31
|
+
|
32
|
+
def use_in_array
|
33
|
+
a1 = Test1.map {|e| e.in_array }
|
34
|
+
a2 = Test2.map {|e| e.in_array }
|
35
|
+
end
|
36
|
+
|
37
|
+
def use_accel_in_array
|
38
|
+
a1 = Test1.map {|e| e.accel_in_array }
|
39
|
+
a2 = Test2.map {|e| e.accel_in_array }
|
40
|
+
end
|
41
|
+
|
42
|
+
def use_slow_in_array
|
43
|
+
a1 = Test1.map {|e| e.slow_in_array }
|
44
|
+
a2 = Test2.map {|e| e.slow_in_array }
|
45
|
+
end
|
46
|
+
|
47
|
+
Benchmark.ips do |x|
|
48
|
+
x.report("Process with in_array") { use_in_array }
|
49
|
+
x.report("Process with hash[] ") { use_accel_in_array }
|
50
|
+
x.report("Process with include?") { use_slow_in_array }
|
51
|
+
x.compare!
|
52
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require "benchmark/ips"
|
2
|
+
require 'in_array'
|
3
|
+
|
4
|
+
class Object
|
5
|
+
def slow_in_array
|
6
|
+
if self.is_a? Array
|
7
|
+
self
|
8
|
+
else
|
9
|
+
[ self ]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
Test1 = (1..100).to_a
|
15
|
+
Test2 = Array(100) { |i| [ i ] }
|
16
|
+
|
17
|
+
def use_in_array
|
18
|
+
a1 = Test1.map {|e| e.in_array }
|
19
|
+
a2 = Test2.map {|e| e.in_array }
|
20
|
+
end
|
21
|
+
|
22
|
+
def use_slow_in_array
|
23
|
+
a1 = Test1.map {|e| e.slow_in_array }
|
24
|
+
a2 = Test2.map {|e| e.slow_in_array }
|
25
|
+
end
|
26
|
+
|
27
|
+
Benchmark.ips do |x|
|
28
|
+
x.report("Process with in_array") { use_in_array }
|
29
|
+
x.report("Process with is_a? ") { use_slow_in_array }
|
30
|
+
x.compare!
|
31
|
+
end
|
data/lib/in_array/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: in_array
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Camilleri
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-04-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest_visible
|
@@ -103,8 +103,9 @@ extra_rdoc_files:
|
|
103
103
|
files:
|
104
104
|
- ".gitignore"
|
105
105
|
- Gemfile
|
106
|
-
- Gemfile.lock
|
107
106
|
- README.md
|
107
|
+
- bench/complex_bench.rb
|
108
|
+
- bench/simple_bench.rb
|
108
109
|
- in_array.gemspec
|
109
110
|
- lib/in_array.rb
|
110
111
|
- lib/in_array/version.rb
|
data/Gemfile.lock
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
in_array (0.1.2)
|
5
|
-
|
6
|
-
GEM
|
7
|
-
remote: https://rubygems.org/
|
8
|
-
specs:
|
9
|
-
json (1.8.1)
|
10
|
-
minitest (4.7.5)
|
11
|
-
rainbow (2.0.0)
|
12
|
-
rake (10.3.2)
|
13
|
-
rdoc (4.0.1)
|
14
|
-
json (~> 1.4)
|
15
|
-
reek (1.3.8)
|
16
|
-
rainbow (>= 1.99, < 3.0)
|
17
|
-
ruby2ruby (>= 2.0.8, < 3.0)
|
18
|
-
ruby_parser (~> 3.3)
|
19
|
-
sexp_processor
|
20
|
-
ruby2ruby (2.1.3)
|
21
|
-
ruby_parser (~> 3.1)
|
22
|
-
sexp_processor (~> 4.0)
|
23
|
-
ruby_parser (3.6.3)
|
24
|
-
sexp_processor (~> 4.1)
|
25
|
-
sexp_processor (4.4.4)
|
26
|
-
|
27
|
-
PLATFORMS
|
28
|
-
x86-mingw32
|
29
|
-
|
30
|
-
DEPENDENCIES
|
31
|
-
bundler (~> 1.3)
|
32
|
-
in_array!
|
33
|
-
minitest (~> 4.7.5)
|
34
|
-
rake
|
35
|
-
rdoc (~> 4.0.1)
|
36
|
-
reek (~> 1.3.8)
|