enums 1.3.1 → 1.4.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 65a45b808ac04efdf1cf4b9b299b61882d691605
4
- data.tar.gz: fc6259850c15fe3f81ee5d8e2bebf4d40f0a754f
3
+ metadata.gz: 3fd8c533a33e8a97a70892813fe984a95e9a296f
4
+ data.tar.gz: f8fc99c3b73a0473b3fe2717d86fd538bf85bdb0
5
5
  SHA512:
6
- metadata.gz: f4875a80e70ac8099ce8b79b92ec6385edced9606a4e873c2ffd3709dd2d454d6057c4aab302c5fa6f4a78999dd79bf36a0fc910ee216af1bbdaaccdc764f25a
7
- data.tar.gz: 38c9a7a44081ecad43ebd9431c3149f48632466499dfea0029532dd036013e8a59add6cd33996cd96cccd61c170e24d3b7ad8803fb41c5c39359d71e20556ba1
6
+ metadata.gz: 30521b0da15ad85a970ef1fbfae486a4f987501dbd5b729fb370df89e8f0cb179fed63951274374c63322ba93c76ebdd16c6e9a646084f7f2ea960fc81eac30c
7
+ data.tar.gz: a8d14b650496db549103d58c19d028186a4451887fb46115ac09afcd4177a7f8612cbefdf33ca0c4b804e6c87ff39c1b65a43f88848687d87c8d8fff2ed909ac
data/README.md CHANGED
@@ -32,8 +32,8 @@ module Color
32
32
  BLUE = 1
33
33
  GREEN = 2
34
34
  end
35
- Color::RED #=> 0
36
- Color::BLUE #=> 1
35
+ Color::RED #=> 0
36
+ Color::BLUE #=> 1
37
37
  Color.constants #=> [:RED, :BLUE, :GREEN]
38
38
  # ...
39
39
  ```
@@ -210,14 +210,30 @@ enum :FileAttrib, [:read_only, :hidden, :system, :archive], flags: true
210
210
  # -or -
211
211
  enum :FileAttrib, :read_only, :hidden, :system, :archive, flags: true
212
212
  # -or -
213
- enum :FileAttrib, { read_only: 1<<0, # 2^0 = 1 = 0b00000001
214
- hidden: 1<<1, # 2^1 = 2 = 0b00000010
215
- system: 1<<2, # 2^2 = 4 = 0b00000100
216
- archive: 1<<5, # 2^5 = 32 = 0b00100000
213
+ enum :FileAttrib, { read_only: Bit(0),
214
+ hidden: Bit(1),
215
+ system: Bit(2),
216
+ archive: Bit(5),
217
217
  },
218
218
  flags: true
219
219
  ```
220
220
 
221
+ Aside: What's `Bit()`?
222
+
223
+ `Bit()` is a bit conversion helper defined as `def Bit(n) 1 << n; end`. Example:
224
+
225
+ | | Bit Shift | Binary | Decimal | Hex |
226
+ |-----------|------------|---------------|-------------|---------|
227
+ | `Bit(0)` | `1<<0` | `0b00000001` | `2^0 = 1` | `0x01` |
228
+ | `Bit(1)` | `1<<1` | `0b00000010` | `2^1 = 2` | `0x02` |
229
+ | `Bit(2)` | `1<<2` | `0b00000100` | `2^2 = 4` | `0x04` |
230
+ | `Bit(3)` | `1<<3` | `0b00001000` | `2^3 = 8` | `0x08` |
231
+ | `Bit(4)` | `1<<4` | `0b00010000` | `2^4 = 16` | `0x10` |
232
+ | `Bit(5)` | `1<<5` | `0b00100000` | `2^5 = 32` | `0x20` |
233
+ | ... |
234
+
235
+
236
+
221
237
  (Auto-)builds a class and code like:
222
238
 
223
239
  ``` ruby
@@ -232,11 +248,11 @@ end
232
248
  class FileAttrib < Flag
233
249
 
234
250
  NONE = new( :none, 0 )
235
- READ_ONLY = new( :read_only, 1<<0 )
236
- HIDDEN = new( :hidden, 1<<1 )
237
- SYSTEM = new( :system, 1<<2 )
238
- ARCHIVE = new( :archive, 1<<3 )
239
- ALL = new( :all, 1<<0|1<<1|1<<2|1<<3 )
251
+ READ_ONLY = new( :read_only, Bit(0) )
252
+ HIDDEN = new( :hidden, Bit(1) )
253
+ SYSTEM = new( :system, Bit(2) )
254
+ ARCHIVE = new( :archive, Bit(3) )
255
+ ALL = new( :all, Bit(0)|Bit(1)|Bit(2)|Bit(3) )
240
256
 
241
257
  def self.none() NONE; end
242
258
  def self.read_only() READ_ONLY; end
@@ -245,7 +261,7 @@ class FileAttrib < Flag
245
261
  def self.archive() ARCHIVE; end
246
262
  def self.all() ALL; end
247
263
 
248
- def self.values() [1<<0,1<<1,1<<2,1<<3]; end
264
+ def self.values() [Bit(0),Bit(1),Bit(2),Bit(3)]; end
249
265
  def self.keys() [:read_only, :hidden, :system, :archive]; end
250
266
  def self.members() [READ_ONLY, HIDDEN, SYSTEM, ARCHIVE]; end
251
267
 
@@ -258,11 +274,11 @@ class FileAttrib < Flag
258
274
  def self.[]( key ) self.key( key ); end
259
275
 
260
276
  def none? @value == 0; end
261
- def read_only?() @value & 1<<0 == 1<<0; end
262
- def hidden?() @value & 1<<1 == 1<<1; end
263
- def system?() @value & 1<<2 == 1<<2; end
264
- def archive?() @value & 1<<3 == 1<<3; end
265
- def all?() @value == 1<<0|1<<1|1<<2|1<<3; end
277
+ def read_only?() @value & Bit(0) == Bit(0); end
278
+ def hidden?() @value & Bit(1) == Bit(1); end
279
+ def system?() @value & Bit(2) == Bit(2); end
280
+ def archive?() @value & Bit(3) == Bit(3); end
281
+ def all?() @value == Bit(0)|Bit(1)|Bit(2)|Bit(3); end
266
282
 
267
283
  def member?( other ) @value & other.value == other.value; end
268
284
 
@@ -348,9 +364,9 @@ enum :TextStyle, [:bold, :italic, :underline], flags: true
348
364
  # -or -
349
365
  enum :TextStyle, :bold, :italic, :underline, flags: true
350
366
  # -or -
351
- enum :TextStyle, { bold: 1<<0,
352
- italic: 1<<1,
353
- underline: 1<<2
367
+ enum :TextStyle, { bold: Bit(0),
368
+ italic: Bit(1),
369
+ underline: Bit(2)
354
370
  },
355
371
  flags: true
356
372
 
@@ -401,6 +417,8 @@ style.is_a? TextStyle #=> true
401
417
  and so on.
402
418
 
403
419
 
420
+
421
+
404
422
  ### What about enums for (algebraic) union data types with variants?
405
423
 
406
424
  Yes, yes, yes. Use the `Union` class or the `data` helper from the safedata library.
@@ -10,6 +10,9 @@ require 'enums/version' # note: let version always go first
10
10
 
11
11
  ## forward declarations
12
12
  module Safe
13
+
14
+ ## todo/check/discuss: auto-include SafeHelper - why? why not?
15
+
13
16
  ## note: use ClassMethods pattern for auto-including class methods
14
17
  ## note ClassMethods module is called SafeHelper
15
18
  def self.included( klass )
@@ -26,6 +29,11 @@ module Safe
26
29
  end # module Safe
27
30
 
28
31
 
32
+ module Kernel
33
+ def Bit( n ) 1 << n; end ## add "global" bit conversion helper
34
+ end
35
+
36
+
29
37
 
30
38
  require 'enums/enum'
31
39
  require 'enums/enum_builder'
@@ -16,6 +16,28 @@ class Enum
16
16
  self
17
17
  end
18
18
 
19
+ def self._typecheck_enum!( o )
20
+ if o.instance_of?( self )
21
+ o
22
+ else
23
+ raise TypeError.new( "[Enum] enum >#{name}< type expected; got >#{o.class.inspect}<" )
24
+ end
25
+ end
26
+ def _typecheck_enum!( o ) self.class._typecheck_enum!( o ); end
27
+
28
+
29
+ def ==( other )
30
+ if other.is_a?( Integer ) && other == 0 ## note: only allow compare by zero (0) integer - why? why not?
31
+ @value == 0
32
+ else
33
+ @value == _typecheck_enum!( other ).value
34
+ end
35
+ end
36
+ alias_method :eql?, :==
37
+
38
+
39
+
40
+
19
41
 
20
42
  def self.keys
21
43
  @keys ||= members.map {|member| member.key}.freeze
@@ -29,11 +51,12 @@ class Enum
29
51
  @hash_by_key[key]
30
52
  end
31
53
 
32
- def self.[]( key ) ## convenience alias for key
33
- self.key( key )
54
+ class << self
55
+ alias_method :[], :key ## convenience alias for key
34
56
  end
35
57
 
36
58
 
59
+
37
60
  def self.values
38
61
  @values ||= members.map {|member| member.value}.freeze
39
62
  @values
@@ -48,12 +71,13 @@ class Enum
48
71
 
49
72
 
50
73
  def self.zero() members[0]; end
51
- def zero?() self == self.class.zero; end
74
+ def zero?() self == self.class.zero; end ## note: use compare by identity (object_id) and NOT value e.g. 0
52
75
 
53
76
 
54
77
  def self.size() keys.size; end
55
- def self.length() size; end ## alias (as is the ruby tradition)
56
-
78
+ class << self
79
+ alias_method :length, :size ## alias (as is the ruby tradition)
80
+ end
57
81
 
58
82
  def self.convert( arg )
59
83
  ## todo/check: support keys too - why? why not?
@@ -62,5 +86,14 @@ class Enum
62
86
  ## note: will ALWAYS look-up by (member) index and NOT by value (integer number value might be different!!)
63
87
  members[ arg ]
64
88
  end
89
+
90
+
91
+ ## add to_i, to_int - why? why not?
92
+ def to_i() @value; end
93
+ def to_int() @value; end ## allows Integer( .. )
94
+
95
+ def to_b() parse_bool(); end
96
+ def parse_bool() @value != 0; end ## nonzero == true, zero == false like numbers
97
+ alias_method :to_bool, :parse_bool
65
98
  end # class Enum
66
99
  end # module Safe
@@ -18,7 +18,7 @@ class Flag
18
18
  end
19
19
 
20
20
  def self._typecheck_flag!( o )
21
- if self == o.class
21
+ if o.instance_of?( self )
22
22
  o
23
23
  else
24
24
  raise TypeError.new( "[Flag] flag >#{name}< type expected; got >#{o.class.inspect}<" )
@@ -38,12 +38,10 @@ class Flag
38
38
 
39
39
 
40
40
  def ==( other )
41
- if self.class == other.class
42
- @value == other.value
43
- elsif other.is_a?( Integer ) ## note: also allow compare by "plain" integer
44
- @value == other
41
+ if other.is_a?( Integer ) && other == 0 ## note: only allow compare by zero (0) integer - why? why not?
42
+ @value == 0
45
43
  else
46
- false
44
+ @value == _typecheck_flag!( other ).value
47
45
  end
48
46
  end
49
47
  alias_method :eql?, :==
@@ -103,8 +101,8 @@ class Flag
103
101
  @hash_by_key[key]
104
102
  end
105
103
 
106
- def self.[]( key ) ## convenience alias for key
107
- self.key( key )
104
+ class << self
105
+ alias_method :[], :key ## convenience alias for key
108
106
  end
109
107
 
110
108
 
@@ -154,8 +152,13 @@ class Flag
154
152
 
155
153
  ## add size|length too why? why not?
156
154
 
155
+
157
156
  ## add to_i, to_int - why? why not?
158
- ## def to_i() @value; end
159
- ## def to_int() @value; end
157
+ def to_i() @value; end
158
+ def to_int() @value; end ## allows Integer( .. )
159
+
160
+ def to_b() parse_bool(); end
161
+ def parse_bool() @value != 0; end ## nonzero == true, zero == false like numbers
162
+ alias_method :to_bool, :parse_bool
160
163
  end # class Flag
161
164
  end # module Safe
@@ -5,8 +5,8 @@
5
5
  module Enums
6
6
 
7
7
  MAJOR = 1
8
- MINOR = 3
9
- PATCH = 1
8
+ MINOR = 4
9
+ PATCH = 0
10
10
  VERSION = [MAJOR,MINOR,PATCH].join('.')
11
11
 
12
12
  def self.version
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: enums
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-03-29 00:00:00.000000000 Z
11
+ date: 2019-03-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rdoc