typesafe_enum 0.1.6 → 0.1.7
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/CHANGES.md +14 -1
- data/README.md +36 -5
- data/lib/typesafe_enum/base.rb +38 -4
- data/lib/typesafe_enum/module_info.rb +1 -1
- data/spec/unit/typesafe_enum/base_spec.rb +15 -0
- data/typesafe_enum.gemspec +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a03ce1356a736037c69f793aaffb12ffe001b4e8
|
4
|
+
data.tar.gz: 3d748bba73a6df9a5f2bf929c379ef2a2ca904b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f8437ae0afc6f20a003ca259fedf412378ffdea8c9090b17cc9271326cb78a0c43dd8dda22a3df31c32d468b94ea8e7edbb3b586ca8c582c967ac7c447da1a03
|
7
|
+
data.tar.gz: c55260cab261cc0273cfc61ca0eaaf686f57ecda9d18d8ea6c13e237e12ae97bd4909fc1ce54bd1545d2f4fb50c7e9c5d38cd04572e4d39172db3a71790dfc80
|
data/CHANGES.md
CHANGED
@@ -1,6 +1,19 @@
|
|
1
|
+
## 0.1.7 (28 April 2016)
|
2
|
+
|
3
|
+
- The default `to_s` for `TypesafeEnum::Base` now includes the enum's class, key, value,
|
4
|
+
and ordinal, e.g.
|
5
|
+
|
6
|
+
Suit::DIAMONDS.to_s
|
7
|
+
# => "Suit::DIAMONDS [1] -> diamonds"
|
8
|
+
|
9
|
+
(Fixes [#5](https://github.com/dmolesUC3/typesafe_enum/issues/5).)
|
10
|
+
- `::find_by_value_str` now uses a hash lookup like the other `::find_by` methods.
|
11
|
+
- Improved method documentation.
|
12
|
+
|
1
13
|
## 0.1.6 (15 Mar 2016)
|
2
14
|
|
3
|
-
- [#3](https://github.com/dmolesUC3/typesafe_enum/pull/3) - No need for `instance_eval`
|
15
|
+
- [#3](https://github.com/dmolesUC3/typesafe_enum/pull/3) - No need for `instance_eval`
|
16
|
+
when creating new enum instance methods - [@dblock](https://github.com/dblock).
|
4
17
|
|
5
18
|
## 0.1.5 (27 Jan 2016)
|
6
19
|
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# TypesafeEnum
|
2
2
|
|
3
3
|
[](https://travis-ci.org/dmolesUC3/typesafe_enum)
|
4
4
|
[](https://codeclimate.com/github/dmolesUC3/typesafe_enum)
|
@@ -9,6 +9,28 @@ A Ruby implementation of Joshua Bloch's
|
|
9
9
|
[typesafe enum pattern](http://www.oracle.com/technetwork/java/page1-139488.html#replaceenums),
|
10
10
|
with syntax loosely inspired by [Ruby::Enum](https://github.com/dblock/ruby-enum).
|
11
11
|
|
12
|
+
## Table of contents
|
13
|
+
|
14
|
+
- [Basic usage](#basic-usage)
|
15
|
+
- [Ordering](#ordering)
|
16
|
+
- [String representations](#string-representations)
|
17
|
+
- [Convenience methods on enum classes](#convenience-methods-on-enum-classes)
|
18
|
+
- [::to\_a](#to_a)
|
19
|
+
- [::size](#size)
|
20
|
+
- [::each, ::each\_with\_index, and ::map](#each-each_with_index-and-map)
|
21
|
+
- [::find\_by\_key, ::find\_by\_value, ::find\_by\_ord](#find_by_key-find_by_value-find_by_ord)
|
22
|
+
- [::find\_by\_value\_str](#find_by_value_str)
|
23
|
+
- [Enum classes with methods](#enum-classes-with-methods)
|
24
|
+
- [Enum instances with methods](#enum-instances-with-methods)
|
25
|
+
- [How is this different from Ruby::Enum?](#how-is-this-different-from-rubyenum)
|
26
|
+
- [How is this different from java.lang.Enum?](#how-is-this-different-from-javalangenum)
|
27
|
+
- [Clunkier syntax](#clunkier-syntax)
|
28
|
+
- [No special switch/case support](#no-special-switchcase-support)
|
29
|
+
- [No serialization support](#no-serialization-support)
|
30
|
+
- [No support classes](#no-support-classes)
|
31
|
+
- [Enum classes are not closed](#enum-classes-are-not-closed)
|
32
|
+
- [Contributing](#contributing)
|
33
|
+
|
12
34
|
## Basic usage
|
13
35
|
|
14
36
|
Create a new enum class and a set of instances:
|
@@ -165,6 +187,18 @@ Suit::SPADES > Tarot::CUPS
|
|
165
187
|
# ArgumentError: comparison of Suit with Tarot failed
|
166
188
|
```
|
167
189
|
|
190
|
+
## String representations
|
191
|
+
|
192
|
+
The default `to_s` implementation provides the enum's class, key, value,
|
193
|
+
and ordinal, e.g.
|
194
|
+
|
195
|
+
```ruby
|
196
|
+
Suit::DIAMONDS.to_s
|
197
|
+
# => "Suit::DIAMONDS [1] -> diamonds"
|
198
|
+
```
|
199
|
+
|
200
|
+
It can of course be overridden.
|
201
|
+
|
168
202
|
## Convenience methods on enum classes
|
169
203
|
|
170
204
|
### `::to_a`
|
@@ -229,9 +263,6 @@ Scale.find_by_value_str('1000000')
|
|
229
263
|
# => #<Scale:0x007f8513a93810 @key=:MEGA, @value=1000000, @ord=3>
|
230
264
|
```
|
231
265
|
|
232
|
-
(Note that unlike the other `::find_by…` methods, which use hash lookups, `::find_by_value_str`
|
233
|
-
is linear in the number of enum values, so it's best suited for smaller enumerations.)
|
234
|
-
|
235
266
|
## Enum classes with methods
|
236
267
|
|
237
268
|
Enum classes are just classes. They can have methods, and other non-enum constants.
|
@@ -334,7 +365,7 @@ Bar::BAR == 1
|
|
334
365
|
```
|
335
366
|
|
336
367
|
Java introduced the concept of "typesafe enums", first as a
|
337
|
-
[design pattern](
|
368
|
+
[design pattern](http://www.oracle.com/technetwork/java/page1-139488.html#replaceenums)
|
338
369
|
and later as a
|
339
370
|
[first-class language construct](https://docs.oracle.com/javase/1.5.0/docs/guide/language/enums.html).
|
340
371
|
In Java, an `Enum` class defines a closed, valued set of _instances of that class,_ rather than
|
data/lib/typesafe_enum/base.rb
CHANGED
@@ -8,50 +8,65 @@ module TypesafeEnum
|
|
8
8
|
class << self
|
9
9
|
|
10
10
|
# Returns an array of the enum instances in declaration order
|
11
|
+
# @return [Array<self>] All instances of this enum, in declaration order
|
11
12
|
def to_a
|
12
13
|
as_array.dup
|
13
14
|
end
|
14
15
|
|
15
16
|
# Returns the number of enum instances
|
17
|
+
# @return [Integer] the number of instances
|
16
18
|
def size
|
17
19
|
as_array ? as_array.length : 0
|
18
20
|
end
|
19
21
|
|
20
22
|
# Iterates over the set of enum instances
|
23
|
+
# @yield [self] Each instance of this enum, in declaration order
|
24
|
+
# @return [Array<self>] All instances of this enum, in declaration order
|
21
25
|
def each(&block)
|
22
26
|
to_a.each(&block)
|
23
27
|
end
|
24
28
|
|
25
29
|
# Iterates over the set of enum instances
|
30
|
+
# @yield [self, Integer] Each instance of this enum, in declaration order,
|
31
|
+
# with its ordinal index
|
32
|
+
# @return [Array<self>] All instances of this enum, in declaration order
|
26
33
|
def each_with_index(&block)
|
27
34
|
to_a.each_with_index(&block)
|
28
35
|
end
|
29
36
|
|
30
37
|
# Iterates over the set of enum instances
|
38
|
+
# @yield [self] Each instance of this enum, in declaration order
|
39
|
+
# @return [Array] An array containing the result of applying `&block`
|
40
|
+
# to each instance of this enum, in instance declaration order
|
31
41
|
def map(&block)
|
32
42
|
to_a.map(&block)
|
33
43
|
end
|
34
44
|
|
35
45
|
# Looks up an enum instance based on its key
|
46
|
+
# @param key [Symbol] the key to look up
|
47
|
+
# @return [self, nil] the corresponding enum instance, or nil
|
36
48
|
def find_by_key(key)
|
37
49
|
by_key[key]
|
38
50
|
end
|
39
51
|
|
40
52
|
# Looks up an enum instance based on its value
|
53
|
+
# @param value [Object] the value to look up
|
54
|
+
# @return [self, nil] the corresponding enum instance, or nil
|
41
55
|
def find_by_value(value)
|
42
56
|
by_value[value]
|
43
57
|
end
|
44
58
|
|
45
59
|
# Looks up an enum instance based on the string representation of its value
|
60
|
+
# @param value_str [String] the string form of the value
|
61
|
+
# @return [self, nil] the corresponding enum instance, or nil
|
46
62
|
def find_by_value_str(value_str)
|
47
63
|
value_str = value_str.to_s
|
48
|
-
|
49
|
-
return instance if value_str == value.to_s
|
50
|
-
end
|
51
|
-
nil
|
64
|
+
by_value_str[value_str]
|
52
65
|
end
|
53
66
|
|
54
67
|
# Looks up an enum instance based on its ordinal
|
68
|
+
# @param ord [Integer] the ordinal to look up
|
69
|
+
# @return [self, nil] the corresponding enum instance, or nil
|
55
70
|
def find_by_ord(ord)
|
56
71
|
return nil if ord < 0 || ord > size
|
57
72
|
as_array[ord]
|
@@ -67,6 +82,10 @@ module TypesafeEnum
|
|
67
82
|
@by_value ||= {}
|
68
83
|
end
|
69
84
|
|
85
|
+
def by_value_str
|
86
|
+
@by_value_str ||= {}
|
87
|
+
end
|
88
|
+
|
70
89
|
def as_array
|
71
90
|
@as_array ||= []
|
72
91
|
end
|
@@ -91,23 +110,34 @@ module TypesafeEnum
|
|
91
110
|
const_set(key.to_s, instance)
|
92
111
|
by_key[key] = instance
|
93
112
|
by_value[value] = instance
|
113
|
+
by_value_str[value.to_s] = instance
|
94
114
|
as_array << instance
|
95
115
|
end
|
96
116
|
end
|
97
117
|
|
98
118
|
# The symbol key for the enum instance
|
119
|
+
# @return [Symbol] the key
|
99
120
|
attr_reader :key
|
121
|
+
|
100
122
|
# The value encapsulated by the enum instance
|
123
|
+
# @return [Object] the value
|
101
124
|
attr_reader :value
|
125
|
+
|
102
126
|
# The ordinal of the enum instance, in declaration order
|
127
|
+
# @return [Integer] the ordinal
|
103
128
|
attr_reader :ord
|
104
129
|
|
105
130
|
# Compares two instances of the same enum class based on their declaration order
|
131
|
+
# @param other [self] the enum instance to compare
|
132
|
+
# @return [Integer, nil] -1 if this value precedes `other`; 0 if the two are
|
133
|
+
# the same enum instance; 1 if this value follows `other`; `nil` if `other`
|
134
|
+
# is not an instance of this enum class
|
106
135
|
def <=>(other)
|
107
136
|
ord <=> other.ord if self.class == other.class
|
108
137
|
end
|
109
138
|
|
110
139
|
# Generates a Fixnum hash value for this enum instance
|
140
|
+
# @return [Fixnum] the hash value
|
111
141
|
def hash
|
112
142
|
@hash ||= begin
|
113
143
|
result = 17
|
@@ -117,6 +147,10 @@ module TypesafeEnum
|
|
117
147
|
end
|
118
148
|
end
|
119
149
|
|
150
|
+
def to_s
|
151
|
+
"#{self.class}::#{key} [#{ord}] -> #{value}"
|
152
|
+
end
|
153
|
+
|
120
154
|
private
|
121
155
|
|
122
156
|
def initialize(key, value = nil, &block)
|
@@ -294,6 +294,21 @@ module TypesafeEnum
|
|
294
294
|
end
|
295
295
|
end
|
296
296
|
|
297
|
+
describe '#to_s' do
|
298
|
+
it 'provides an informative string' do
|
299
|
+
aggregate_failures 'informative string' do
|
300
|
+
[Suit, Tarot, RGBColor, Scale].each do |ec|
|
301
|
+
ec.each do |ev|
|
302
|
+
result = ev.to_s
|
303
|
+
[ec.to_s, ev.key, ev.ord, ev.value].each do |info|
|
304
|
+
expect(result).to include("#{info}")
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
297
312
|
describe '::find_by_key' do
|
298
313
|
it 'maps symbol keys to enum instances' do
|
299
314
|
keys = [:CLUBS, :DIAMONDS, :HEARTS, :SPADES]
|
data/typesafe_enum.gemspec
CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |spec|
|
|
15
15
|
spec.license = 'MIT'
|
16
16
|
|
17
17
|
origin = `git config --get remote.origin.url`.chomp
|
18
|
-
origin_uri = origin.start_with?('http') ? URI(origin) : URI(origin.
|
18
|
+
origin_uri = origin.start_with?('http') ? URI(origin) : URI(origin.gsub(%r{git@([^:]+)(.com|.org)[^\/]+}, 'http://\1\2'))
|
19
19
|
spec.homepage = URI::HTTP.build(host: origin_uri.host, path: origin_uri.path.chomp('.git')).to_s
|
20
20
|
|
21
21
|
spec.files = `git ls-files -z`.split("\x0")
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: typesafe_enum
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Moles
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-04-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|