enums 1.3.1 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
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