qo 0.1.4 → 0.1.5

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: a097911edc42e2a5ebf4ef3ea3fde3493ab82ae4
4
- data.tar.gz: 7233bc3005d008543c13a2083b0f7e6560194b0f
3
+ metadata.gz: 42970cef4c751efed91fe25ec0aeaaa09e4a60e1
4
+ data.tar.gz: fc6439c832bec23e75e0e080686ce2ab5e82ec5e
5
5
  SHA512:
6
- metadata.gz: e53d71122117634454907e9fbe0b960a38aa7bedcebecb9faa876f8da2febd54e0f7da94278bae75bc75740697d2c37f7d8e81677ab0c31d915ffdb45ce7afea
7
- data.tar.gz: 329801b537a3ac7d08e2f08741152fe3ca86265a4dc10178121ccc3aaa2f0230b64a882d0e8a509b7713e3dd1638dd987df6f5ee0d2b753c0aaa00bf3bff441a
6
+ metadata.gz: 1fbb43ae9bd6393399fedd716aafb843f666270db54517f40144ce1d74b57b2e799d8e23bf47fc16c2e05e646c5b2db16dfa5bd5e528801049e60c5cd360cf81
7
+ data.tar.gz: 92e752aa74d56eabcec5ea245373a647939869a325d582779600e49cef7095e076ccbd839938e9bfaae7978a9909e6490e526fd9e9d0b50cbd9268bb10e944cf
data/.pryrc ADDED
@@ -0,0 +1,34 @@
1
+ class Person
2
+ attr_reader :name, :age
3
+
4
+ def initialize(name, age)
5
+ @name = name
6
+ @age = age
7
+ end
8
+
9
+ def adult?
10
+ @age > 17
11
+ end
12
+
13
+ def cool?
14
+ @name.include?('Rob')
15
+ end
16
+
17
+ def to_h
18
+ {name: @name, age: @age}
19
+ end
20
+ end
21
+
22
+ people_arrays = [
23
+ ['Robert', 22],
24
+ ['Roberta', 22],
25
+ ['Foo', 42],
26
+ ['Bar', 18]
27
+ ]
28
+
29
+ people_objects = [
30
+ Person.new('Robert', 22),
31
+ Person.new('Roberta', 22),
32
+ Person.new('Foo', 42),
33
+ Person.new('Bar', 17),
34
+ ]
data/README.md CHANGED
@@ -356,11 +356,39 @@ people_hashes.select(&Qo[age: :nil?])
356
356
  # => []
357
357
  ```
358
358
 
359
- ### 4 - Hacky Fun Time
359
+ ### 4 - Right Hand Pattern Matching
360
+
361
+ > ALPHA - This feature is alpha, currently testing. Considering whether or not to add `or` and `not` as `m_or` and `m_not`.
362
+
363
+ This is where I start going a bit off into the weeds. We're going to try and get RHA style pattern matching in Ruby.
364
+
365
+ ```ruby
366
+ Qo.match(['Robert', 22],
367
+ Qo.m(:*, 20..99) { |n, a| "#{n} is an adult that is #{a} years old" },
368
+ Qo.m(:*)
369
+ )
370
+ # => "Robert is an adult that is 22 years old"
371
+ ```
372
+
373
+ ```ruby
374
+ Qo.match(people_objects.first,
375
+ Qo.m(name: :*, age: 20..99) { |person| "#{person.name} is an adult that is #{person.age} years old" },
376
+ Qo.m(:*)
377
+ )
378
+ ```
379
+
380
+ In this case it's trying to do a few things:
381
+
382
+ 1. Iterate over every matcher until it finds a match
383
+ 2. Execute its block function
384
+
385
+ If no block function is provided, it assumes an identity function (`-> v { v }`) instead. If no match is found, `nil` will be returned.
386
+
387
+ ### 5 - Hacky Fun Time
360
388
 
361
389
  These examples will grow over the next few weeks as I think of more fun things to do with Qo. PRs welcome if you find fun uses!
362
390
 
363
- #### 4.1 - JSON
391
+ #### 5.1 - JSON
364
392
 
365
393
  Qo tries to be clever though, it assumes Symbol keys first and then String keys, so how about some JSON?:
366
394
 
@@ -376,9 +404,9 @@ posts.select(&Qo[userId: 1])
376
404
 
377
405
  Nifty!
378
406
 
379
- #### 4.2 - Opsy Stuff
407
+ #### 5.2 - Opsy Stuff
380
408
 
381
- ##### 4.2.1 - NMap
409
+ ##### 5.2.1 - NMap
382
410
 
383
411
  What about NMap for our Opsy friends? Well, simulated, but still fun.
384
412
 
data/lib/qo.rb CHANGED
@@ -1,22 +1,39 @@
1
1
  require "qo/version"
2
2
  require 'qo/matcher'
3
+ require 'qo/guard_block_matcher'
3
4
 
4
5
  module Qo
5
6
  WILDCARD_MATCH = :*
6
7
 
7
- def self.and(*array_matchers, **keyword_matchers)
8
- Qo::Matcher.new('and', *array_matchers, **keyword_matchers)
9
- end
8
+ class << self
9
+ def m(*array_matchers, **keyword_matchers, &fn)
10
+ Qo::GuardBlockMatcher.new(*array_matchers, **keyword_matchers, &fn)
11
+ end
10
12
 
11
- def self.[](*array_matchers, **keyword_matchers)
12
- Qo::Matcher.new('and', *array_matchers, **keyword_matchers)
13
- end
13
+ def match(data, *qo_matchers)
14
+ all_are_guards = qo_matchers.all? { |q| q.is_a?(Qo::GuardBlockMatcher)}
15
+ raise 'Must patch Qo GuardBlockMatchers!' unless all_are_guards
14
16
 
15
- def self.or(*array_matchers, **keyword_matchers)
16
- Qo::Matcher.new('or', *array_matchers, **keyword_matchers)
17
- end
17
+ qo_matchers.reduce(nil) { |_, matcher|
18
+ did_match, match_result = matcher.call(data)
19
+ break match_result if did_match
20
+ }
21
+ end
22
+
23
+ def and(*array_matchers, **keyword_matchers)
24
+ Qo::Matcher.new('and', *array_matchers, **keyword_matchers)
25
+ end
26
+
27
+ def [](*array_matchers, **keyword_matchers)
28
+ Qo::Matcher.new('and', *array_matchers, **keyword_matchers)
29
+ end
30
+
31
+ def or(*array_matchers, **keyword_matchers)
32
+ Qo::Matcher.new('or', *array_matchers, **keyword_matchers)
33
+ end
18
34
 
19
- def self.not(*array_matchers, **keyword_matchers)
20
- Qo::Matcher.new('not', *array_matchers, **keyword_matchers)
35
+ def not(*array_matchers, **keyword_matchers)
36
+ Qo::Matcher.new('not', *array_matchers, **keyword_matchers)
37
+ end
21
38
  end
22
39
  end
@@ -0,0 +1,19 @@
1
+ module Qo
2
+ class GuardBlockMatcher < Matcher
3
+ IDENTITY = -> v { v }
4
+
5
+ def initialize(*array_matchers, **keyword_matchers, &fn)
6
+ @fn = fn || IDENTITY
7
+
8
+ super('and', *array_matchers, **keyword_matchers)
9
+ end
10
+
11
+ def to_proc
12
+ -> match_target {
13
+ return [false, false] unless super[match_target]
14
+
15
+ [true, @fn.call(match_target)]
16
+ }
17
+ end
18
+ end
19
+ end
@@ -1,3 +1,3 @@
1
1
  module Qo
2
- VERSION = '0.1.4'
2
+ VERSION = '0.1.5'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandon Weaver
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-04-11 00:00:00.000000000 Z
11
+ date: 2018-04-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -88,6 +88,7 @@ extensions: []
88
88
  extra_rdoc_files: []
89
89
  files:
90
90
  - ".gitignore"
91
+ - ".pryrc"
91
92
  - ".rspec"
92
93
  - ".travis.yml"
93
94
  - CODE_OF_CONDUCT.md
@@ -99,6 +100,7 @@ files:
99
100
  - bin/console
100
101
  - bin/setup
101
102
  - lib/qo.rb
103
+ - lib/qo/guard_block_matcher.rb
102
104
  - lib/qo/matcher.rb
103
105
  - lib/qo/version.rb
104
106
  - qo.gemspec