enumerated_type 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +7 -0
- data/lib/enumerated_type.rb +27 -4
- data/lib/enumerated_type/version.rb +1 -1
- data/test/enumerated_type_spec.rb +11 -1
- metadata +19 -5
- checksums.yaml +0 -15
data/README.md
CHANGED
@@ -195,6 +195,13 @@ JobStatus.by(:display, "pending-1") # => #<JobStatus:pending>
|
|
195
195
|
```
|
196
196
|
If more than one instance of your `EnumeratedType` matches, the first match will be returned, in the order the types were `declared`.
|
197
197
|
|
198
|
+
If you pass a bock to .by, it will be executed and its value returned (just like Hash#fetch). This is useful for defining a default value or a custom error message.
|
199
|
+
|
200
|
+
```ruby
|
201
|
+
JobStatus.by(:display, "does-not-exist") { JobStatus::FAILURE } # => #<JobStatus:failure>
|
202
|
+
JobStatus.by(:display, "does-not-exist") { |v| raise("I have no idea what to do with #{v.inspect}") } # => raises an exception
|
203
|
+
```
|
204
|
+
|
198
205
|
## Development
|
199
206
|
|
200
207
|
To run the tests (assuming you have already run `gem install bundler`):
|
data/lib/enumerated_type.rb
CHANGED
@@ -1,7 +1,29 @@
|
|
1
1
|
require "enumerated_type/version"
|
2
2
|
|
3
3
|
module EnumeratedType
|
4
|
-
|
4
|
+
# In the unfortunate case where there are thousands of elements in an
|
5
|
+
# enumerated type, an iteration based strategy for EnumeratedType.by is slow.
|
6
|
+
# Particularly, since declare does .by(:name, name) to detect name
|
7
|
+
# collisions, EnumeratedType.declare is O(n^2) where n is the
|
8
|
+
# EnumeratedType.count, which can take seconds when the enunm is loaded,
|
9
|
+
# which is, like, a total bummer. This class indexes enums by property and
|
10
|
+
# value so lookups are constant time. The backing hash would look like this
|
11
|
+
# for the Shape enum.
|
12
|
+
#
|
13
|
+
# {
|
14
|
+
# :sides => {
|
15
|
+
# 4 => Shape::Square
|
16
|
+
# },
|
17
|
+
# :name => {
|
18
|
+
# :square => Shape::Square
|
19
|
+
# }
|
20
|
+
# }
|
21
|
+
#
|
22
|
+
# Note that there is only a single value for each property/value combination.
|
23
|
+
# #set will respect the first instance of a property/value combination (i.e
|
24
|
+
# subsequent duplicate #sets will not override the first value). This matches
|
25
|
+
# the definition of EnumeratedType.by.
|
26
|
+
class PropertyIndex
|
5
27
|
def initialize
|
6
28
|
self.by_property = { }
|
7
29
|
end
|
@@ -27,7 +49,7 @@ module EnumeratedType
|
|
27
49
|
def self.included(base)
|
28
50
|
base.instance_eval do
|
29
51
|
@all = []
|
30
|
-
@by_cache =
|
52
|
+
@by_cache = PropertyIndex.new
|
31
53
|
|
32
54
|
attr_reader :name, :value
|
33
55
|
|
@@ -77,12 +99,12 @@ module EnumeratedType
|
|
77
99
|
end
|
78
100
|
|
79
101
|
def by(property, value, &miss)
|
80
|
-
miss ||= Proc.new { raise(ArgumentError, "Could not find #{self.name} with ##{property} == #{
|
102
|
+
miss ||= Proc.new { |v| raise(ArgumentError, "Could not find #{self.name} with ##{property} == #{v.inspect}'") }
|
81
103
|
|
82
104
|
if @by_cache.has_property?(property)
|
83
105
|
@by_cache.get(property, value, miss)
|
84
106
|
else
|
85
|
-
find { |e| e.send(property) == value } || miss.call
|
107
|
+
find { |e| e.send(property) == value } || miss.call(value)
|
86
108
|
end
|
87
109
|
end
|
88
110
|
|
@@ -121,6 +143,7 @@ module EnumeratedType
|
|
121
143
|
end
|
122
144
|
|
123
145
|
attr_accessor(:"#{property}")
|
146
|
+
public(:"#{property}")
|
124
147
|
private(:"#{property}=")
|
125
148
|
end
|
126
149
|
|
@@ -190,7 +190,7 @@ describe EnumeratedType do
|
|
190
190
|
Shapes.by(:sides, 4).must_equal(Shapes::RECTANGLE)
|
191
191
|
end
|
192
192
|
|
193
|
-
it "raises an argument if there is no match" do
|
193
|
+
it "raises an argument if there is no match and no block given" do
|
194
194
|
lambda { Shapes.by(:sides, 6) }.must_raise(ArgumentError)
|
195
195
|
end
|
196
196
|
|
@@ -198,6 +198,10 @@ describe EnumeratedType do
|
|
198
198
|
(Shapes.by(:sides, 6) { "UnknownShape"}).must_equal("UnknownShape")
|
199
199
|
end
|
200
200
|
|
201
|
+
it "passes the value to the block" do
|
202
|
+
(Shapes.by(:sides, 6) { |sides| "No shape with #{sides} sides" }).must_equal("No shape with 6 sides")
|
203
|
+
end
|
204
|
+
|
201
205
|
it "returns the first declared value if there is more than one match" do
|
202
206
|
Shapes.by(:pretty_hip, "YEAH").must_equal(Shapes::TRIANGLE)
|
203
207
|
end
|
@@ -205,6 +209,12 @@ describe EnumeratedType do
|
|
205
209
|
it "works with arbitrary methods" do
|
206
210
|
Shapes.by(:sides_squared, 16).must_equal(Shapes::RECTANGLE)
|
207
211
|
end
|
212
|
+
|
213
|
+
it "passes the value to the block for arbitrary methods" do
|
214
|
+
(Shapes.by(:sides_squared, 3) { |sides| "No shape with #{sides} sides squared" }).must_equal("No shape with 3 sides squared")
|
215
|
+
end
|
216
|
+
|
217
|
+
|
208
218
|
end
|
209
219
|
|
210
220
|
describe "#inspect" do
|
metadata
CHANGED
@@ -1,18 +1,20 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: enumerated_type
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.1
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Rafer Hazen
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2015-07-16 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: bundler
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
16
18
|
requirements:
|
17
19
|
- - ~>
|
18
20
|
- !ruby/object:Gem::Version
|
@@ -20,6 +22,7 @@ dependencies:
|
|
20
22
|
type: :development
|
21
23
|
prerelease: false
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
23
26
|
requirements:
|
24
27
|
- - ~>
|
25
28
|
- !ruby/object:Gem::Version
|
@@ -27,6 +30,7 @@ dependencies:
|
|
27
30
|
- !ruby/object:Gem::Dependency
|
28
31
|
name: minitest
|
29
32
|
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
30
34
|
requirements:
|
31
35
|
- - ~>
|
32
36
|
- !ruby/object:Gem::Version
|
@@ -34,6 +38,7 @@ dependencies:
|
|
34
38
|
type: :development
|
35
39
|
prerelease: false
|
36
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
37
42
|
requirements:
|
38
43
|
- - ~>
|
39
44
|
- !ruby/object:Gem::Version
|
@@ -41,6 +46,7 @@ dependencies:
|
|
41
46
|
- !ruby/object:Gem::Dependency
|
42
47
|
name: rake
|
43
48
|
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
44
50
|
requirements:
|
45
51
|
- - ~>
|
46
52
|
- !ruby/object:Gem::Version
|
@@ -48,6 +54,7 @@ dependencies:
|
|
48
54
|
type: :development
|
49
55
|
prerelease: false
|
50
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
51
58
|
requirements:
|
52
59
|
- - ~>
|
53
60
|
- !ruby/object:Gem::Version
|
@@ -71,26 +78,33 @@ files:
|
|
71
78
|
homepage: https://github.com/rafer/enumerated_type
|
72
79
|
licenses:
|
73
80
|
- MIT
|
74
|
-
metadata: {}
|
75
81
|
post_install_message:
|
76
82
|
rdoc_options: []
|
77
83
|
require_paths:
|
78
84
|
- lib
|
79
85
|
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
80
87
|
requirements:
|
81
88
|
- - ! '>='
|
82
89
|
- !ruby/object:Gem::Version
|
83
90
|
version: '0'
|
91
|
+
segments:
|
92
|
+
- 0
|
93
|
+
hash: 491884112611942535
|
84
94
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
85
96
|
requirements:
|
86
97
|
- - ! '>='
|
87
98
|
- !ruby/object:Gem::Version
|
88
99
|
version: '0'
|
100
|
+
segments:
|
101
|
+
- 0
|
102
|
+
hash: 491884112611942535
|
89
103
|
requirements: []
|
90
104
|
rubyforge_project:
|
91
|
-
rubygems_version:
|
105
|
+
rubygems_version: 1.8.23.2
|
92
106
|
signing_key:
|
93
|
-
specification_version:
|
107
|
+
specification_version: 3
|
94
108
|
summary: Simple enumerated types
|
95
109
|
test_files:
|
96
110
|
- test/enumerated_type_spec.rb
|
checksums.yaml
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
---
|
2
|
-
!binary "U0hBMQ==":
|
3
|
-
metadata.gz: !binary |-
|
4
|
-
MGRiNTE1NTQ1ZjI5N2IwMGM4ZmVlNjEzYjFhYjNjMGFkNDY1MjdiYQ==
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
NDM3MDI1NjczOTVmY2E2ZmQwOTQyZWYxMzk5NWFkNTZmNjFlNTdhZQ==
|
7
|
-
SHA512:
|
8
|
-
metadata.gz: !binary |-
|
9
|
-
NGU1MjA4OGRkYTU4MDU2MjdlMmI0MjM1NzYwMWRiYTk5Mzg4ZjNiYjgxZjll
|
10
|
-
NDQxNWM1NTA2MjZmYTU4ZmQ5NTJiZjA3Mjk2ZGNlMmUyNGRlYTFhNWU2Njk5
|
11
|
-
MWM1MjM2MDBmNTE0MzQ2YmI5OGYyNmVmNGUyNjQzZWM1ZWQ3N2M=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
NDA5MzBmYmNjN2UyMGFlZjA2YTIwYmIzYjVlNjRjMGM2N2YwYjA3ZWFlNDAw
|
14
|
-
ZDk0OTNlYjk3YTRkNDY4NmUwODg0NjIwMDdiODU4YmZiMDFhZjJkZmMwZmE1
|
15
|
-
MjFkYmFjYzg3MDA1MmZlYjhkY2JmYzExM2JhMmYyYTNlNGUzNzI=
|