in_array 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|