ioughta 0.2.1 → 0.3.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: 0c12c98fe08970c112e895a81c1a235bfc89c34b
4
- data.tar.gz: 69c50f6794139a6ccb84c51630a418ef33381eb0
3
+ metadata.gz: 7918cd422602dfb4b8d10a0a22a41ecd7385d092
4
+ data.tar.gz: 529732cd9cfc9f3e8dc9f11422aaaa43dea9a35e
5
5
  SHA512:
6
- metadata.gz: d8ee63a12106312f5701f9ddc2b7c2ded8b77e8febcb19a16ee94205de2ad4fcf290f75da6b8b1448e92e0a3ebfec5b977d01f3e395e83853b969464d384d6dc
7
- data.tar.gz: 1a9382fdfdf9c4a57bdb58eb12e3f373d7db4e42e93922cb85b2e9174ccffb86e8de3341bb6b5a78e59bf042da657d052a41514ba4d8589f44fca975fc9e426b
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 Go-like constants and hashes in Ruby using iota.
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
- Here's an example, written in Go:
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 // 1 << 0 which is 00000001
20
- IgChocolate // 1 << 1 which is 00000010
21
- IgNuts // 1 << 2 which is 00000100
22
- IgStrawberries // 1 << 3 which is 00001000
23
- IgShellfish // 1 << 4 which is 00010000
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
- Here it is in Ruby, using ioughta:
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.ioughta_hash(->(i) { 1 << i }, %i[
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[:strawberries] # => 8
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 (`0`) and increments for
80
- each constant. The default lambda is simply `:itself`, so you can very easily
81
- create a sequence of constants with consecutive integer values:
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 to generate future
101
- values from the iterator. In Go parlance, this is (apparently) known as
102
- *implicit repetition of the last non-empty expression list*. You can redefine
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, proc(&:itself) # restore the default behavior (6 => 6)
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.ioughta_const ->(i) { 1 << (10 * i) }, %i[_ KB MB GB TB PB EB ZB YB]
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| 1 << (10 * i) }.freeze
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
- monkeypatching and/or dynamic dispatch. No such limitation exists when
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` methods are too ugly for you (I don't
141
- blame you), they're aliased as `iota_const` and `iota_hash`, respectively.
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 Go-like constants and hashes using iota'
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
- each_resolved_pair(pair(data, &block)) do |nom, val|
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
- each_resolved_pair(pair(data, &block)).to_h
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 pair(data, &block)
27
- data = data.flatten
28
- lam =
29
- if block
30
- block
31
- elsif data.first.respond_to?(:call)
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 each_resolved_pair(data)
52
- return enum_for(__method__, data) { data.length / 2 } unless block_given?
35
+ def each_resolved_ipair(*args)
36
+ return enum_for(__method__, *args) unless block_given?
53
37
 
54
- data.each_slice(2).with_index do |(nom, lam), iota|
55
- val = lam.call(*[iota, nom].take(lam.arity.abs))
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
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: false
2
2
  module Ioughta
3
- VERSION = '0.2.1'.freeze
3
+ VERSION = '0.3.0'.freeze
4
4
  end
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.2.1
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-14 00:00:00.000000000 Z
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 Go-like constants and hashes using iota
96
+ summary: Helpers for defining sequences of constants in Ruby using a Go-like syntax
97
97
  test_files: []