hamstar 0.0.3 → 0.0.4

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: f8ac2cc619b90cd952f777392b2b5eeee655de44
4
- data.tar.gz: 00805291596cc8e7522c106b6bd02aeb7f399ed4
3
+ metadata.gz: f7e20abd0e1bdc5dcacbe0334893f80cac4cc639
4
+ data.tar.gz: 3385c91113d9d36c1056fed5b1731940b4bc27d4
5
5
  SHA512:
6
- metadata.gz: ead258d56878dfbcaa20955b918b6bfa380a3f0e17b2280e628e612ede29564f34b8057f20543f2089f2b149542edba85bba1e01e0c9c94348d728f1a731164c
7
- data.tar.gz: 184f0adbfa8877e65be6ad7f35d60e009bb50c7baefe7d20abdbf9830a7971c81d22d11bb458b88e63713c2228abc053f80a2aaaa2fd2f40488de8bcc97e017a
6
+ metadata.gz: 1e20a8a16cecfe4535001bd1043eaf6ab23a64d69bcf3ba3960b44dc7db32381726c0c3a59a944c57c79a3f65f14a67d533cee23af9714592c859c0228ebb471
7
+ data.tar.gz: 68d4f9fe22a65da1db8dc733768e395e9fbdbd0e521548eb23ae4d835d355c2a989678d944ecc0425d066921e04d60ce3975a90c4448d2286c2f874285f9167f
data/README.md CHANGED
@@ -27,24 +27,38 @@ With plain old `update_in()` you can:
27
27
 
28
28
  ```ruby
29
29
  require 'hamster'
30
- x = [{name:'Chris', hobbies:['clarinet']},{name:'Pat',hobbies:['bird watching','rugby']}]
31
- Hamster.from(x).update_in(1,:name){|name| 'Patsy'}
30
+ x = Hamster.from([{name:'Chris', hobbies:['clarinet']},{name:'Pat',hobbies:['bird watching','rugby']}])
31
+ x.update_in(1,:name){|name| 'Patsy'}
32
32
  => Hamster::Vector[Hamster::Hash[:hobbies => Hamster::Vector["clarinet"], :name => "Chris"], Hamster::Hash[:hobbies => Hamster::Vector["bird watching", "rugby"], :name => "Patsy"]]
33
33
  ```
34
34
 
35
- With Hamstar you can write code that is a little more flexibly:
35
+ You can do the exact same thing with Hamstar's `update_having()`:
36
36
 
37
37
  ```ruby
38
38
  require 'hamstar'
39
- Hamstar.update_having( Hamster.from(x), 1,:name){|name| 'Patsy'}
39
+ Hamstar.update_having( x, 1,:name){|name| 'Patsy'}
40
40
  => (same result as before)
41
41
  ```
42
42
 
43
43
  And you can go further, and replace the vector offset `1` with the Kleene star `'*'` to operate on all elements of the vector:
44
44
 
45
45
  ```ruby
46
- Hamstar.update_having( Hamster.from(x), '*',:name){|name| 'Patsy'}
47
- => (same result as before)
46
+ Hamstar.update_having( x, '*',:name){|name| name + 'sy'}
47
+ => Hamster::Vector[Hamster::Hash[:name => "Chrissy", :hobbies => Hamster::Vector["clarinet"]], Hamster::Hash[:name => "Patsy", :hobbies => Hamster::Vector["bird watching", "rugby"]]]
48
+ ```
49
+
50
+ And what if you wanted to efficiently replace every 'Pat' with 'Patsy', without having to add conditional code to your block? Hamstar let's you use a key/value pair as part of your path specification:
51
+
52
+ ```ruby
53
+ Hamstar.update_having( x, [:name,'Pat'],:name){|name| 'Patsy'}
54
+ => Hamster::Vector[Hamster::Hash[:name => "Chris", :hobbies => Hamster::Vector["clarinet"]], Hamster::Hash[:name => "Patsy", :hobbies => Hamster::Vector["bird watching", "rugby"]]]
55
+ ```
56
+
57
+ Finally, you can use a `Proc` as a matcher e.g.
58
+
59
+ ```ruby
60
+ Hamstar.update_having( x, ->(k,v,expr){v[:name] == 'Pat'},:name){|name| 'Patsy'}
61
+ => Hamster::Vector[Hamster::Hash[:name => "Chris", :hobbies => Hamster::Vector["clarinet"]], Hamster::Hash[:name => "Patsy", :hobbies => Hamster::Vector["bird watching", "rugby"]]]
48
62
  ```
49
63
 
50
64
  See [`hamstar_spec.rb`](file://spec/hamstar_spec.rb) for more examples.
@@ -5,44 +5,38 @@ require 'hamster'
5
5
  module Hamstar
6
6
 
7
7
  KLEENE_STAR = '*'
8
+ MATCH_KLEENE_STAR = ->(k,v,expr){true}
9
+ MATCH_ASSOCIATION = ->(k,v,expr){key,value=expr; v[key] == value}
8
10
 
9
11
  module_function
10
12
 
11
- def update_having(c, *key_path, &block)
12
- if key_path.empty?
13
- raise ArgumentError, "must have at least one key in path"
13
+ def update_having(c, *match_path, &block)
14
+ if match_path.empty?
15
+ raise ArgumentError, "must have at least one matcher in path"
14
16
  end
15
- key = key_path[0]
16
- case key
17
- when KLEENE_STAR; kleene_star c, *key_path, &block
18
- when Array, Hamster::Vector; association c, *key_path, &block
17
+ matcher = match_path[0]
18
+ case matcher
19
+ when KLEENE_STAR; match MATCH_KLEENE_STAR, c, *match_path, &block
20
+ when Array, Hamster::Vector; match MATCH_ASSOCIATION, c, *match_path, &block
21
+ when Proc; match matcher, c, *match_path, &block
19
22
  else
20
- if key_path.size == 1
21
- new_value = block.call c.fetch(key,nil)
23
+ if match_path.size == 1
24
+ new_value = block.call c.fetch(matcher,nil)
22
25
  else
23
- value = c.fetch key, Hamster::EmptyHash
24
- new_value = update_having value, *key_path[1..-1], &block
26
+ value = c.fetch matcher, Hamster::EmptyHash
27
+ new_value = update_having value, *match_path[1..-1], &block
25
28
  end
26
- c.put key, new_value
29
+ c.put matcher, new_value
27
30
  end
28
31
  end
29
32
 
30
- def kleene_star(c, *key_path, &block)
31
- kp_rest = Hamster.from(key_path)[1..-1] # drop kleene star
32
- c.keys.each do |key|
33
- kp = kp_rest.unshift key # put key where kleene star was
34
- c = update_having c, *kp, &block
35
- end
36
- c
37
- end
38
-
39
- def association(c, *key_path, &block)
40
- key,value = key_path[0]
41
- kp_rest = Hamster.from(key_path)[1..-1] # drop assoc
42
- c.each_pair do |k,v|
43
- if v[key] == value
44
- kp = kp_rest.unshift k # put key where assoc was
45
- c = update_having c, *kp, &block
33
+ def match(matcher, c, *match_path, &block)
34
+ expr = match_path[0]
35
+ mp_rest = Hamster.from(match_path)[1..-1] # drop expr
36
+ c.each_pair do |key,value|
37
+ if matcher.call key, value, expr
38
+ mp = mp_rest.unshift key # put key where assoc was
39
+ c = update_having c, *mp, &block
46
40
  end
47
41
  end
48
42
  c
@@ -1,3 +1,3 @@
1
1
  module Hamstar
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -13,14 +13,20 @@ RSpec.describe Hamstar do
13
13
  examples_kleene_star = [
14
14
  [ {a:1,b:2}, ['*'], ->(v){v+1}, {a:2,b:3}, 'top level Hash'],
15
15
  [ [1,2], ['*'], ->(v){v+1}, [2,3], 'top level Vector'],
16
- [ {a:[1],b:[2]},['*', 0], ->(v){v+1}, {a:[2],b:[3]}, 'Vector underneath Hash'],
17
- [ [{a:1},{a:2}],['*', :a], ->(v){v+1}, [{a:2},{a:3}], 'Hash underneath Vector']
16
+ [ {a:[1],b:[2]},[:b, '*'], ->(v){v+1}, {a:[1],b:[3]}, 'Hash containing Vector'],
17
+ [ [{a:1},{a:2}],[0, '*'], ->(v){v+1}, [{a:2},{a:2}], 'Vector containing Hash'],
18
+ [ {a:[1],b:[2]},['*', 0], ->(v){v+1}, {a:[2],b:[3]}, 'Vector inside Hash'],
19
+ [ [{a:1},{a:2}],['*', :a], ->(v){v+1}, [{a:2},{a:3}], 'Hash inside Vector']
18
20
  ]
19
21
 
20
22
  examples_associative = [
21
23
  [ [{name:'Chris'},{name:'Pat'}], [ [:name, 'Pat'], :name ], ->(name){name<<'sy'}, [{name:'Chris'},{name:'Patsy'}], 'modify matching Hash']
22
24
  ]
23
25
 
26
+ examples_function_match = [
27
+ [ [1,2], [->(k,v,expr){v==2}], ->(v){5}, [1,5] ]
28
+ ]
29
+
24
30
  def self.write_examples(examples)
25
31
  examples.each do |e|
26
32
  it e[4] do
@@ -40,5 +46,8 @@ RSpec.describe Hamstar do
40
46
  describe 'New association matching' do
41
47
  write_examples examples_associative
42
48
  end
49
+ describe 'New functional matching' do
50
+ write_examples examples_function_match
51
+ end
43
52
 
44
53
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hamstar
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bill Burcham
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-01 00:00:00.000000000 Z
11
+ date: 2015-11-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hamster