hamstar 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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