lab42_nhash 0.1.1 → 0.1.2
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 +4 -4
- data/Gemfile.lock +1 -1
- data/demo/090-compound-values.md +53 -0
- data/lib/lab42/nhash/enum.rb +36 -0
- data/lib/lab42/nhash/version.rb +1 -1
- data/spec/unit/compound/enum_spec.rb +25 -33
- data/spec/unit/compound/get_spec.rb +38 -0
- data/spec/unit/compound/hash_enum_spec.rb +49 -0
- metadata +6 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 61f49c29e0db80ae41ba77a021fa52ddff6c8358
|
|
4
|
+
data.tar.gz: d82b50f5129c0dc580647654593f64179a0a95fb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7d2f0c0e1426d9034430be22df2f220463413b75d13069e40533aa8e31226493b1ae5fce8a887a51f1ab6ce0b40fe0964f03ede6275f7ee04635106b07c1775b
|
|
7
|
+
data.tar.gz: 12bab1e9b0f31058465e54b72fb12cce5641148c29ae864eeac1e5636b2c5afb15e4b10c6a6555a95fb55640391e9a200c47474220bfb2398a0cb5d373b48bd9
|
data/Gemfile.lock
CHANGED
data/demo/090-compound-values.md
CHANGED
|
@@ -45,6 +45,59 @@ And that we can also use interpolation:
|
|
|
45
45
|
# entries[0].get!(:value).assert == '42'
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
+
### Enhanced Search
|
|
49
|
+
|
|
50
|
+
`NHash::Enum` of course implements `Enumerable`. However, when looking for keys we need to rescue from `KeyError` very frequently.
|
|
51
|
+
|
|
52
|
+
Here is a demonstration of that.
|
|
53
|
+
|
|
54
|
+
```ruby
|
|
55
|
+
nh = NHash.new(
|
|
56
|
+
entries: [
|
|
57
|
+
{a: 1},
|
|
58
|
+
{b: 2}
|
|
59
|
+
])
|
|
60
|
+
.with_indifferent_access
|
|
61
|
+
entries = nh.get :entries
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
In order to find `b` the quite obvious code is
|
|
65
|
+
|
|
66
|
+
```ruby
|
|
67
|
+
entries.find{ |entry|
|
|
68
|
+
begin
|
|
69
|
+
entry.get(:b)
|
|
70
|
+
rescue KeyError
|
|
71
|
+
end
|
|
72
|
+
}.get(:b).assert == 2
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Now that code is not very readable, is it? Being cluttered by the rescue block and needing to invoke the get again?
|
|
76
|
+
|
|
77
|
+
Here is how we would like to write (and read) that kind of code:
|
|
78
|
+
|
|
79
|
+
```ruby
|
|
80
|
+
entries.get{ |entry|
|
|
81
|
+
entry.get :b
|
|
82
|
+
}.assert == 2
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
This can even be shortened to
|
|
86
|
+
|
|
87
|
+
```ruby
|
|
88
|
+
entries.get{ 2 * get(:b) }
|
|
89
|
+
.assert == 4
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
or
|
|
93
|
+
|
|
94
|
+
```ruby
|
|
95
|
+
entries.get(:b).assert == 2
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
48
101
|
|
|
49
102
|
|
|
50
103
|
|
data/lib/lab42/nhash/enum.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
require 'forwarder'
|
|
2
2
|
|
|
3
|
+
require_relative 'invocation'
|
|
4
|
+
|
|
3
5
|
module Lab42
|
|
4
6
|
class NHash
|
|
5
7
|
class Enum
|
|
@@ -11,12 +13,20 @@ module Lab42
|
|
|
11
13
|
forward :last!, to_object: :self, as: :fetch!, with: -1
|
|
12
14
|
|
|
13
15
|
include Enumerable
|
|
16
|
+
include Invocation
|
|
14
17
|
|
|
15
18
|
attr_reader :parent
|
|
16
19
|
|
|
17
20
|
def [] idx
|
|
18
21
|
Lab42::NHash.from_value @enum[idx], @options
|
|
19
22
|
end
|
|
23
|
+
|
|
24
|
+
def each blk=nil, &block
|
|
25
|
+
behavior = blk || block
|
|
26
|
+
@enum.each do | ele |
|
|
27
|
+
behavior.( Lab42::NHash.from_value ele, @options )
|
|
28
|
+
end
|
|
29
|
+
end
|
|
20
30
|
|
|
21
31
|
def fetch! idx
|
|
22
32
|
result = self[ idx ]
|
|
@@ -24,6 +34,12 @@ module Lab42
|
|
|
24
34
|
|
|
25
35
|
ERB.new( result ).result @parent.current_binding
|
|
26
36
|
end
|
|
37
|
+
|
|
38
|
+
def get keyexp=nil, &block
|
|
39
|
+
behavior = block || keyexp
|
|
40
|
+
raise ArgumentError, 'need key or behavior' unless behavior
|
|
41
|
+
Proc === behavior ? _get_with_behavior( behavior ) : _get_with_key( keyexp )
|
|
42
|
+
end
|
|
27
43
|
|
|
28
44
|
private
|
|
29
45
|
def initialize enum, options
|
|
@@ -32,6 +48,26 @@ module Lab42
|
|
|
32
48
|
@options = options
|
|
33
49
|
end
|
|
34
50
|
|
|
51
|
+
def _get_with_key keyexp
|
|
52
|
+
each do |ele, sentinel|
|
|
53
|
+
begin
|
|
54
|
+
return ele.get keyexp
|
|
55
|
+
rescue KeyError
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
raise KeyError, "key not found: #{keyexp.inspect}"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def _get_with_behavior behavior
|
|
62
|
+
each do |ele, sentinel|
|
|
63
|
+
begin
|
|
64
|
+
return _invoke behavior, ele
|
|
65
|
+
rescue KeyError
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
raise KeyError, "key not found: #{keyexp.inspect}"
|
|
69
|
+
|
|
70
|
+
end
|
|
35
71
|
end # class Enum
|
|
36
72
|
end # class NHash
|
|
37
73
|
end # module Lab42
|
data/lib/lab42/nhash/version.rb
CHANGED
|
@@ -1,41 +1,33 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe NHash::Enum do
|
|
4
|
-
subject do
|
|
5
|
-
nh = NHash.new(
|
|
6
|
-
a: 42,
|
|
7
|
-
entries: [
|
|
8
|
-
{ val: '<%= get :a %>' },
|
|
9
|
-
'<%= get(:a) * 2 %>',
|
|
10
|
-
21
|
|
11
|
-
] )
|
|
12
|
-
.with_indifferent_access
|
|
13
|
-
end
|
|
14
|
-
let(:enum){ subject.get :entries }
|
|
15
4
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
5
|
+
context 'Enumerable behavior' do
|
|
6
|
+
context 'Hashes' do
|
|
7
|
+
subject do
|
|
8
|
+
NHash.new( entries: [{a: 1}] ).with_indifferent_access
|
|
9
|
+
end
|
|
10
|
+
let(:entries){ subject.get :entries }
|
|
19
11
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
end
|
|
27
|
-
it 'for #last' do
|
|
28
|
-
expect( enum.last ).to eq 21
|
|
29
|
-
end
|
|
30
|
-
end # context :behaves
|
|
12
|
+
it 'are yielded as NHash instances' do
|
|
13
|
+
entries.each do | entry |
|
|
14
|
+
expect( entry ).to be_kind_of NHash
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end # context 'yields NHashes'
|
|
31
18
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
19
|
+
context 'Arrays' do
|
|
20
|
+
subject do
|
|
21
|
+
NHash.new( entries: [[{a:1}]] ).with_indifferent_access
|
|
22
|
+
end
|
|
23
|
+
let(:entries){ subject.get :entries }
|
|
24
|
+
it 'are yielded as NHash::Enum instances' do
|
|
25
|
+
entries.each do | entry |
|
|
26
|
+
expect( entry ).to be_kind_of described_class
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end # context 'yields NHash::Enum instances'
|
|
31
|
+
end # context 'Enumerable behavior'
|
|
36
32
|
|
|
37
|
-
it 'interpolates in the context of the original object' do
|
|
38
|
-
expect( enum.first.get!('val') ).to eq '42'
|
|
39
|
-
end
|
|
40
|
-
end # context 'preservers the context'
|
|
41
33
|
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe NHash::Enum do
|
|
4
|
+
|
|
5
|
+
subject do
|
|
6
|
+
NHash.new(
|
|
7
|
+
entries: [
|
|
8
|
+
{a: 1},
|
|
9
|
+
{b: 2}
|
|
10
|
+
]
|
|
11
|
+
).with_indifferent_access
|
|
12
|
+
end
|
|
13
|
+
let(:entries){ subject.get :entries }
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
context 'get with keys' do
|
|
17
|
+
it 'finds a key' do
|
|
18
|
+
expect( entries.get :a ).to eq 1
|
|
19
|
+
expect( entries.get :b ).to eq 2
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it '... or not' do
|
|
23
|
+
expect( ->{ entries.get :c } ).to raise_error KeyError
|
|
24
|
+
end
|
|
25
|
+
end # context 'get with keys'
|
|
26
|
+
|
|
27
|
+
context 'get with blox' do
|
|
28
|
+
it 'finds a key and returns the bloxs return value' do
|
|
29
|
+
expect( entries.get{ |e| e.get(:b) * 2 } ).to eq 4
|
|
30
|
+
expect( entries.get(->(e){ e.get(:b) * 2 }) ).to eq 4
|
|
31
|
+
end
|
|
32
|
+
it 'can instance exec the behavior' do
|
|
33
|
+
expect( entries.get{ get(:b) + 1 } ).to eq 3
|
|
34
|
+
expect( entries.get(->{ get(:b) + 1 }) ).to eq 3
|
|
35
|
+
end
|
|
36
|
+
end # context 'get with blox'
|
|
37
|
+
|
|
38
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe NHash::Enum do
|
|
4
|
+
subject do
|
|
5
|
+
nh = NHash.new(
|
|
6
|
+
a: 42,
|
|
7
|
+
entries: [
|
|
8
|
+
{ val: '<%= get :a %>' },
|
|
9
|
+
'<%= get(:a) * 2 %>',
|
|
10
|
+
21
|
|
11
|
+
] )
|
|
12
|
+
.with_indifferent_access
|
|
13
|
+
end
|
|
14
|
+
let(:enum){ subject.get :entries }
|
|
15
|
+
|
|
16
|
+
it 'is returned for arrays' do
|
|
17
|
+
expect( subject.get :entries ).to be_instance_of described_class
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
context 'behaves like an array' do
|
|
21
|
+
it 'for #[]' do
|
|
22
|
+
expect( enum[2] ).to eq 21
|
|
23
|
+
end
|
|
24
|
+
it 'for #first' do
|
|
25
|
+
expect( enum.first.get :val ).to eq '<%= get :a %>'
|
|
26
|
+
end
|
|
27
|
+
it 'for #last' do
|
|
28
|
+
expect( enum.last ).to eq 21
|
|
29
|
+
end
|
|
30
|
+
end # context :behaves
|
|
31
|
+
|
|
32
|
+
context 'behaves like an Enumerable' do
|
|
33
|
+
it 'via Lab42::NHash::Enum' do
|
|
34
|
+
expect( enum ).to be_kind_of described_class
|
|
35
|
+
expect( described_class ).to be < Enumerable
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end # context 'behaves like an Enumerable'
|
|
39
|
+
|
|
40
|
+
context 'preservers the context' do
|
|
41
|
+
it 'evaluates with indifferent access' do
|
|
42
|
+
expect( enum.first.get('val') ).to eq '<%= get :a %>'
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it 'interpolates in the context of the original object' do
|
|
46
|
+
expect( enum.first.get!('val') ).to eq '42'
|
|
47
|
+
end
|
|
48
|
+
end # context 'preservers the context'
|
|
49
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lab42_nhash
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Robert Dober
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2014-05-
|
|
11
|
+
date: 2014-05-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: forwarder2
|
|
@@ -168,6 +168,8 @@ files:
|
|
|
168
168
|
- spec/unit/afixes/prefix_spec.rb
|
|
169
169
|
- spec/unit/afixes/suffix_spec.rb
|
|
170
170
|
- spec/unit/compound/enum_spec.rb
|
|
171
|
+
- spec/unit/compound/get_spec.rb
|
|
172
|
+
- spec/unit/compound/hash_enum_spec.rb
|
|
171
173
|
- spec/unit/compound/nhash_spec.rb
|
|
172
174
|
- spec/unit/factories/from_sources_using_hashes_spec.rb
|
|
173
175
|
- spec/unit/factories/from_sources_using_yaml_files_spec.rb
|
|
@@ -224,6 +226,8 @@ test_files:
|
|
|
224
226
|
- spec/unit/afixes/prefix_spec.rb
|
|
225
227
|
- spec/unit/afixes/suffix_spec.rb
|
|
226
228
|
- spec/unit/compound/enum_spec.rb
|
|
229
|
+
- spec/unit/compound/get_spec.rb
|
|
230
|
+
- spec/unit/compound/hash_enum_spec.rb
|
|
227
231
|
- spec/unit/compound/nhash_spec.rb
|
|
228
232
|
- spec/unit/factories/from_sources_using_hashes_spec.rb
|
|
229
233
|
- spec/unit/factories/from_sources_using_yaml_files_spec.rb
|