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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dfa964b499cd8f9c9fb458f0082eacf0f990cfac
4
- data.tar.gz: f5c06457ecdd6652fd05a33e768791192993a37d
3
+ metadata.gz: 61f49c29e0db80ae41ba77a021fa52ddff6c8358
4
+ data.tar.gz: d82b50f5129c0dc580647654593f64179a0a95fb
5
5
  SHA512:
6
- metadata.gz: aacab0eb78da5bbeb5b945624e0c2fa058634ba87731dee6803cae4caf27c9e9d21f8910b18a75579528a167d556417b1caeb25bdcea512ca31fd3e614d3f779
7
- data.tar.gz: 7aa8904790917d875576b024692427ea49fe3b252096aca527b3c25f101d8afb7a035822262f9a41533cc6d4c402ef68eeefa9afecd893d92f3a86f8c9e8d52d
6
+ metadata.gz: 7d2f0c0e1426d9034430be22df2f220463413b75d13069e40533aa8e31226493b1ae5fce8a887a51f1ab6ce0b40fe0964f03ede6275f7ee04635106b07c1775b
7
+ data.tar.gz: 12bab1e9b0f31058465e54b72fb12cce5641148c29ae864eeac1e5636b2c5afb15e4b10c6a6555a95fb55640391e9a200c47474220bfb2398a0cb5d373b48bd9
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- lab42_nhash (0.1.1)
4
+ lab42_nhash (0.1.2)
5
5
  forwarder2 (~> 0.2)
6
6
  ruby_parser (~> 3.6)
7
7
 
@@ -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
 
@@ -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
@@ -1,5 +1,5 @@
1
1
  module Lab42
2
2
  class NHash
3
- VERSION = '0.1.1'
3
+ VERSION = '0.1.2'
4
4
  end # class NHash
5
5
  end # module Lab42
@@ -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
- it 'is returned for arrays' do
17
- expect( subject.get :entries ).to be_instance_of described_class
18
- end
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
- 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
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
- context 'preservers the context' do
33
- it 'evaluates with indifferent access' do
34
- expect( enum.first.get('val') ).to eq '<%= get :a %>'
35
- end
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.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-27 00:00:00.000000000 Z
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