enumerated_type 0.4.0 → 0.4.1

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.
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`):
@@ -1,7 +1,29 @@
1
1
  require "enumerated_type/version"
2
2
 
3
3
  module EnumeratedType
4
- class ByCache
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 = ByCache.new
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} == #{value.inspect}'") }
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
 
@@ -1,3 +1,3 @@
1
1
  module EnumeratedType
2
- VERSION = "0.4.0"
2
+ VERSION = "0.4.1"
3
3
  end
@@ -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.0
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: 2014-09-11 00:00:00.000000000 Z
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: 2.3.0
105
+ rubygems_version: 1.8.23.2
92
106
  signing_key:
93
- specification_version: 4
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=