ioughta 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +51 -27
- data/ioughta.gemspec +1 -1
- data/lib/ioughta.rb +12 -30
- data/lib/ioughta/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7918cd422602dfb4b8d10a0a22a41ecd7385d092
|
4
|
+
data.tar.gz: 529732cd9cfc9f3e8dc9f11422aaaa43dea9a35e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c64d851fb46da155fb80c475ba9ae391cb3deee69106f196e35a5c9c99a45b275ddc4d6f8197cdd98164b2614a44cc58dac40d9f2d33cd2eb3a0204711257a7
|
7
|
+
data.tar.gz: c7ac30fba3192205a238ac82b4fb3833a523b0f7c063611ab5bee3ad3e1baaf85d4e43d8434ab09a26ea401542edaf23710753a52ea2a037189c2eb55e52958b
|
data/README.md
CHANGED
@@ -3,28 +3,36 @@
|
|
3
3
|
[![Build Status](https://travis-ci.org/mwpastore/ioughta.svg?branch=master)](https://travis-ci.org/mwpastore/ioughta)
|
4
4
|
[![Gem Version](https://badge.fury.io/rb/ioughta.svg)](https://badge.fury.io/rb/ioughta)
|
5
5
|
|
6
|
-
Helpers for defining
|
6
|
+
Helpers for defining sequences of constants in Ruby using a Go-like syntax.
|
7
7
|
|
8
8
|
Go has quite a nice facility for defining constants derived from a sequential
|
9
9
|
value using a [simple and elegant syntax][1], so I thought I'd steal it for
|
10
10
|
Ruby. Rubyists tend to group constants together in hashes rather than littering
|
11
11
|
their programs with countless constants, so there's a mechanism for that, too.
|
12
12
|
|
13
|
-
|
13
|
+
Although there isn't as strong of a need for sequences of constants in Ruby as
|
14
|
+
there is in other languages such as Go, they are still sometimes required when
|
15
|
+
working with external systems such as databases and web APIs for which Ruby
|
16
|
+
symbols don't map cleanly. For example, a database column might store users'
|
17
|
+
privilege levels as 0, 1, or 2, and it would be useful to define constants that
|
18
|
+
map to those values. Ruby doesn't have a native expression for this construct
|
19
|
+
(other than simply defining them one at a time).
|
20
|
+
|
21
|
+
Here's a simple example, written in Go:
|
14
22
|
|
15
23
|
```go
|
16
24
|
type Allergen int
|
17
25
|
|
18
26
|
const (
|
19
|
-
IgEggs Allergen = 1 << iota
|
20
|
-
IgChocolate
|
21
|
-
IgNuts
|
22
|
-
IgStrawberries
|
23
|
-
IgShellfish
|
27
|
+
IgEggs Allergen = 1 << iota // 1 << 0 which is 00000001
|
28
|
+
IgChocolate // 1 << 1 which is 00000010
|
29
|
+
IgNuts // 1 << 2 which is 00000100
|
30
|
+
IgStrawberries // 1 << 3 which is 00001000
|
31
|
+
IgShellfish // 1 << 4 which is 00010000
|
24
32
|
)
|
25
33
|
```
|
26
34
|
|
27
|
-
|
35
|
+
And here it is in Ruby, using ioughta:
|
28
36
|
|
29
37
|
```ruby
|
30
38
|
Object.ioughta_const(
|
@@ -41,15 +49,15 @@ IG_STRAWBERRIES # => 8
|
|
41
49
|
Or, perhaps a bit more Rubyishly:
|
42
50
|
|
43
51
|
```ruby
|
44
|
-
IG = Object.
|
52
|
+
IG = Object.iota_hash(%i[
|
45
53
|
eggs
|
46
54
|
chocolate
|
47
55
|
nuts
|
48
56
|
strawberries
|
49
57
|
shellfish
|
50
|
-
]).freeze
|
58
|
+
]) { |i| 1 << i }.freeze
|
51
59
|
|
52
|
-
IG[:
|
60
|
+
IG[:shellfish] # => 16
|
53
61
|
```
|
54
62
|
|
55
63
|
## Installation
|
@@ -76,9 +84,11 @@ $ gem install ioughta
|
|
76
84
|
|
77
85
|
Ioughta works just like `const` and `iota` do in Go, with only a few minor
|
78
86
|
differences. You must `include` the module in your program, class, or module in
|
79
|
-
order to start using it. The iterator starts at zero (
|
80
|
-
each constant
|
81
|
-
|
87
|
+
order to start using it. The iterator starts at zero (0) and increments for
|
88
|
+
each constant (or hash key) being defined. A function (any Ruby callable) takes
|
89
|
+
the current iteration as input and returns the value to be assigned. The
|
90
|
+
default function simply returns the iterator, so you can easily create
|
91
|
+
sequences of constants with consecutive integer values:
|
82
92
|
|
83
93
|
```ruby
|
84
94
|
require 'ioughta'
|
@@ -86,6 +96,8 @@ include Ioughta
|
|
86
96
|
|
87
97
|
Object.ioughta_const(:FOO, :BAR, :QUX)
|
88
98
|
|
99
|
+
FOO # => 0
|
100
|
+
BAR # => 1
|
89
101
|
QUX # => 2
|
90
102
|
```
|
91
103
|
|
@@ -94,13 +106,14 @@ To skip value(s) in the sequence, use the `:_` symbol:
|
|
94
106
|
```ruby
|
95
107
|
Object.ioughta_const(:_, :FOO, :BAR, :_, :QUX)
|
96
108
|
|
109
|
+
FOO # => 1
|
110
|
+
BAR # => 2
|
97
111
|
QUX # => 4
|
98
112
|
```
|
99
113
|
|
100
|
-
As soon as Ioughta sees a lambda, it will start using it
|
101
|
-
values from the iterator.
|
102
|
-
|
103
|
-
the lambda as many times as you like:
|
114
|
+
As soon as Ioughta sees a lambda (or any Ruby callable), it will start using it
|
115
|
+
to generate future values from the iterator. You can redefine the lambda as
|
116
|
+
many times as you like:
|
104
117
|
|
105
118
|
```ruby
|
106
119
|
Object.ioughta_const(
|
@@ -110,35 +123,42 @@ Object.ioughta_const(
|
|
110
123
|
:D, ->(j) { j ** 3 }, # will cube (3 => 27)
|
111
124
|
:E, # will also cube (4 => 64)
|
112
125
|
:F, # cube all the things (5 => 125)
|
113
|
-
:G,
|
126
|
+
:G, ->{ 0.5 } # will use a simple value (6 => 0.5)
|
127
|
+
:H, proc(&:itself) # restore the default behavior (7 => 7)
|
114
128
|
)
|
115
129
|
```
|
116
130
|
|
117
131
|
You can also pass the lambda as the first argument:
|
118
132
|
|
119
133
|
```ruby
|
120
|
-
Object.
|
134
|
+
Object.Ioughta_const ->(I) { 1 << (10 * I) }, %I[_ KIB MIB GIB TIB PIB EIB ZIB YIB]
|
121
135
|
```
|
122
136
|
|
123
137
|
Or even pass a block, instead of a lambda:
|
124
138
|
|
125
139
|
```ruby
|
126
|
-
BYTES = Object.ioughta_hash(%i[_ KB MB GB TB PB EB ZB YB]) { |i|
|
140
|
+
BYTES = Object.ioughta_hash(%i[_ KB MB GB TB PB EB ZB YB]) { |i| 10 ** (i * 3) }.freeze
|
127
141
|
```
|
128
142
|
|
143
|
+
If the first argument is a lambda *and* a block is given, the block will be
|
144
|
+
silently ignored.
|
145
|
+
|
146
|
+
## Notes
|
147
|
+
|
129
148
|
The only major feature missing from the Go implementation is the ability to
|
130
149
|
perform parallel assignment in the constant list. We're defining a list of
|
131
150
|
terms, not a list of expressions, so it's not possible to do in Ruby without
|
132
|
-
resourcing to nasty `eval` tricks. Don't forget to separate your terms with
|
133
|
-
commas
|
151
|
+
resourcing to nasty `eval` tricks. **Don't forget to separate your terms with
|
152
|
+
commas and freeze your hash constants!**
|
134
153
|
|
135
154
|
You've probably noticed that in order to use Ioughta in the top-level
|
136
155
|
namespace, we need to explicitly specify the `Object` receiver (just like we
|
137
156
|
need to do for `#const_set`). I didn't want to get too crazy with the
|
138
|
-
|
157
|
+
monkey-patching and/or method delegation. No such limitation exists when
|
139
158
|
including Ioughta in a module or class, thanks to the available context. Also,
|
140
|
-
if the `ioughta_const` and `ioughta_hash`
|
141
|
-
blame you), they're aliased as `iota_const` and `iota_hash`,
|
159
|
+
if the `ioughta_const` and `ioughta_hash` method names are too ugly for you (I
|
160
|
+
don't blame you), they're aliased as `iota_const` and `iota_hash`,
|
161
|
+
respectively.
|
142
162
|
|
143
163
|
Here is a very contrived and arbitrary example:
|
144
164
|
|
@@ -163,7 +183,7 @@ MyFileUtils.mask_and_shift(0644, :user) & MyFileUtils::EXECUTE # => 0
|
|
163
183
|
MyFileUtils.mask_and_shift(01777, :special) & MyFileUtils::TACKY # => 1
|
164
184
|
```
|
165
185
|
|
166
|
-
One note on the above: the lambda (or block) can take the key at the current
|
186
|
+
One note on the above: the lambda (or block) can take the "key" at the current
|
167
187
|
iteration as an optional second argument.
|
168
188
|
|
169
189
|
## Development
|
@@ -177,6 +197,10 @@ release a new version, update the version number in `version.rb`, and then run
|
|
177
197
|
git commits and tags, and push the `.gem` file to
|
178
198
|
[rubygems.org](https://rubygems.org).
|
179
199
|
|
200
|
+
## Trivium
|
201
|
+
|
202
|
+
Pronounced /aɪ ˈɔtə/, as in the English phrase "Why, I oughta...!"
|
203
|
+
|
180
204
|
## Contributing
|
181
205
|
|
182
206
|
Bug reports and pull requests are welcome on GitHub at
|
data/ioughta.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.authors = ['Mike Pastore']
|
11
11
|
spec.email = ['mike@oobak.org']
|
12
12
|
|
13
|
-
spec.summary = 'Helpers for defining
|
13
|
+
spec.summary = 'Helpers for defining sequences of constants in Ruby using a Go-like syntax'
|
14
14
|
spec.homepage = 'http://github.com/mwpastore/ioughta'
|
15
15
|
spec.license = 'MIT'
|
16
16
|
|
data/lib/ioughta.rb
CHANGED
@@ -5,7 +5,7 @@ module Ioughta
|
|
5
5
|
def self.included(base)
|
6
6
|
class << base
|
7
7
|
def ioughta_const(*data, &block)
|
8
|
-
|
8
|
+
each_resolved_ipair(data, block) do |nom, val|
|
9
9
|
const_set(nom, val)
|
10
10
|
end
|
11
11
|
end
|
@@ -13,7 +13,7 @@ module Ioughta
|
|
13
13
|
alias_method :iota_const, :ioughta_const
|
14
14
|
|
15
15
|
def ioughta_hash(*data, &block)
|
16
|
-
|
16
|
+
each_resolved_ipair(data, block).to_h
|
17
17
|
end
|
18
18
|
|
19
19
|
alias_method :iota_hash, :ioughta_hash
|
@@ -23,38 +23,20 @@ module Ioughta
|
|
23
23
|
DEFAULT_LAMBDA = proc(&:itself)
|
24
24
|
SKIP_SYMBOL = :_
|
25
25
|
|
26
|
-
def
|
27
|
-
data = data.flatten
|
28
|
-
lam =
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
data.shift
|
33
|
-
else
|
34
|
-
DEFAULT_LAMBDA
|
35
|
-
end
|
36
|
-
|
37
|
-
(0..Float::INFINITY).lazy.each do |i|
|
38
|
-
if i % 2 != 0
|
39
|
-
if data[i].respond_to?(:call)
|
40
|
-
lam = data[i]
|
41
|
-
else
|
42
|
-
data.insert(i, lam)
|
43
|
-
end
|
44
|
-
elsif data[i].nil?
|
45
|
-
break
|
46
|
-
end
|
26
|
+
def each_ipair_with_index(data, block = nil)
|
27
|
+
data = data.to_a.flatten(1)
|
28
|
+
lam = (data.shift if data[0].respond_to?(:call)) || block || DEFAULT_LAMBDA
|
29
|
+
|
30
|
+
data.each_with_index do |nom, i, j = i.succ|
|
31
|
+
yield nom, data[j].respond_to?(:call) ? lam = data.slice!(j) : lam, i
|
47
32
|
end
|
48
|
-
data
|
49
33
|
end
|
50
34
|
|
51
|
-
def
|
52
|
-
return enum_for(__method__,
|
35
|
+
def each_resolved_ipair(*args)
|
36
|
+
return enum_for(__method__, *args) unless block_given?
|
53
37
|
|
54
|
-
|
55
|
-
|
56
|
-
next if nom == SKIP_SYMBOL
|
57
|
-
yield nom, val
|
38
|
+
each_ipair_with_index(*args) do |nom, lam, iota|
|
39
|
+
yield nom, lam.call(*[iota, nom].take(lam.arity.abs)) unless nom == SKIP_SYMBOL
|
58
40
|
end
|
59
41
|
end
|
60
42
|
end
|
data/lib/ioughta/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ioughta
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Pastore
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-09-
|
11
|
+
date: 2016-09-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -93,5 +93,5 @@ rubyforge_project:
|
|
93
93
|
rubygems_version: 2.5.1
|
94
94
|
signing_key:
|
95
95
|
specification_version: 4
|
96
|
-
summary: Helpers for defining
|
96
|
+
summary: Helpers for defining sequences of constants in Ruby using a Go-like syntax
|
97
97
|
test_files: []
|