typesafe_enum 0.1.6 → 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Build Status](https://travis-ci.org/dmolesUC3/typesafe_enum.svg?branch=master)](https://travis-ci.org/dmolesUC3/typesafe_enum)
|
4
4
|
[![Code Climate](https://codeclimate.com/github/dmolesUC3/typesafe_enum.svg)](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
|