eqq 0.0.1 → 0.0.6
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/MIT-LICENSE.txt +1 -1
- data/README.md +122 -5
- data/lib/eqq.rb +39 -217
- data/lib/eqq/buildable.rb +292 -0
- data/lib/eqq/version.rb +2 -1
- data/sig/eqq.rbs +112 -0
- metadata +15 -220
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d0645f6178f68b0a105efa1bcf389bd3c0b1f056cd94a6c6684b0d18bc9284f8
|
4
|
+
data.tar.gz: a93f3a7df8098fbb1e7bdb61b5ad36c29a67e4471e563c63bb562b7896cfa60d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a5d02720dfa28fc5aefed2907008e14e76dc00fd087eb83eb6c89bbf8c976b0258410d554592fc1368938bfcda8e96efc99ae2a811f285dfba33b210bf795ba5
|
7
|
+
data.tar.gz: e8077c6bd4ab3c5e363abeaa5154dca3bf8154140a73f75d238883cefe92855fb8da843ba46037c12ffb9bc710b9449b1d121a6e2119dc774520bd237f71d564
|
data/MIT-LICENSE.txt
CHANGED
@@ -7,7 +7,7 @@ of this software and associated documentation files (the "Software"), to deal
|
|
7
7
|
in the Software without restriction, including without limitation the rights
|
8
8
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
9
|
copies of the Software, and to permit persons to whom the Software is
|
10
|
-
furnished to do so, subject to the following
|
10
|
+
furnished to do so, subject to the following patterns:
|
11
11
|
|
12
12
|
The above copyright notice and this permission notice shall be included in all
|
13
13
|
copies or substantial portions of the Software.
|
data/README.md
CHANGED
@@ -3,18 +3,16 @@
|
|
3
3
|

|
4
4
|
[](http://badge.fury.io/rb/eqq)
|
5
5
|
|
6
|
-
Pattern objects builder
|
7
|
-
|
8
|
-
`eqq` means `#===`
|
6
|
+
Pattern objects builder
|
9
7
|
|
10
8
|
## Usage
|
11
9
|
|
12
|
-
Require Ruby 2.
|
10
|
+
Require Ruby 2.6 or later
|
13
11
|
|
14
12
|
Add below code into your Gemfile
|
15
13
|
|
16
14
|
```ruby
|
17
|
-
gem 'eqq', '>= 0.0.
|
15
|
+
gem 'eqq', '>= 0.0.6', '< 0.1.0'
|
18
16
|
```
|
19
17
|
|
20
18
|
### Overview
|
@@ -29,10 +27,129 @@ require 'eqq'
|
|
29
27
|
pattern = Eqq.define do
|
30
28
|
OR(AND(Float, 20..50), Integer)
|
31
29
|
end
|
30
|
+
|
31
|
+
p pattern #=> "OR(AND(Float, 20..50), Integer)"
|
32
32
|
[4.2, 42, 42.0, 420].grep(pattern) #=> [42, 42.0, 420]
|
33
|
+
|
34
|
+
inverted = Eqq.NOT(pattern)
|
35
|
+
p inverted #=> "NOT(OR(AND(Float, 20..50), Integer))"
|
36
|
+
[4.2, 42, 42.0, 420].grep(inverted) #=> [4.2]
|
37
|
+
|
38
|
+
Eqq.SEND(:all?, pattern) === [4.2, 42, 42.0, 420] #=> false
|
39
|
+
Eqq.SEND(:any?, pattern) === [4.2, 42, 42.0, 420] #=> true
|
40
|
+
|
41
|
+
ret_in_case = (
|
42
|
+
case 42
|
43
|
+
when pattern
|
44
|
+
'Should be matched here! :)'
|
45
|
+
when inverted
|
46
|
+
'Should not be matched here! :<'
|
47
|
+
else
|
48
|
+
'Should not be matched here too! :<'
|
49
|
+
end
|
50
|
+
)
|
51
|
+
|
52
|
+
p ret_in_case #=> Should be matched here! :)
|
53
|
+
|
54
|
+
ret_in_case = (
|
55
|
+
case 4.2
|
56
|
+
when pattern
|
57
|
+
'Should not be matched here! :<'
|
58
|
+
when inverted
|
59
|
+
'Should be matched here! :)'
|
60
|
+
else
|
61
|
+
'Should not be matched here too! :<'
|
62
|
+
end
|
63
|
+
)
|
64
|
+
|
65
|
+
p ret_in_case #=> Should be matched here! :)
|
66
|
+
|
67
|
+
class MyClass
|
68
|
+
include Eqq::Buildable
|
69
|
+
|
70
|
+
def example
|
71
|
+
[4.2, 42, 42.0, 420].grep(OR(AND(Float, 20..50), Integer))
|
72
|
+
end
|
73
|
+
end
|
74
|
+
MyClass.new.example #=> [42, 42.0, 420]
|
33
75
|
```
|
34
76
|
|
77
|
+
### Explanation
|
78
|
+
|
79
|
+
All products can be called as `pattern === other`.
|
80
|
+
|
81
|
+
This signature will fit in most Ruby code.
|
82
|
+
|
83
|
+
* `case ~ when` syntax
|
84
|
+
* Enumerable#grep
|
85
|
+
* Enumerable#grep_v
|
86
|
+
* Enumerable#all?
|
87
|
+
* Enumerable#any?
|
88
|
+
* Enumerable#none?
|
89
|
+
* Enumerable#one?
|
90
|
+
* Enumerable#slice_after
|
91
|
+
* Enumerable#slice_before
|
92
|
+
|
93
|
+
They can take this interface as the `pattern`.
|
94
|
+
|
95
|
+
And you already saw. All of patterns can be mixed with other patterns as a parts.
|
96
|
+
Reuse as you wish!
|
97
|
+
|
98
|
+
### Builders
|
99
|
+
|
100
|
+
* OR(*patterns) - Product returns `true` when matched even one pattern
|
101
|
+
* AND(*patterns) - Product returns `true` when matched all patterns
|
102
|
+
* NOT(pattern) - Product returns `true` when not matched the pattern
|
103
|
+
* CAN(*method_names) - Product returns `true` when it has all of the methods (checked with `respond_to?`)
|
104
|
+
* RESCUE(exception_class/module, pattern) - Product returns `true` when the pattern raises the exception
|
105
|
+
* QUIET(*patterns) - Product returns `true` when all patterns did not raise any exception
|
106
|
+
* EQ(object) - Product returns `true` when matched with `#==`
|
107
|
+
* SAME(object) - Product returns `true` when matched with `#equal?`
|
108
|
+
* SEND(name, pattern) - Basically provided for Enumerable
|
109
|
+
* BOOLEAN() - Product returns `true` when matched to `true` or `false`
|
110
|
+
* ANYTHING() - Product returns `true`, always `true`
|
111
|
+
* NEVER() - Product returns `false`, always `false`
|
112
|
+
* XOR(pattern1, pattern2) - Product returns `true` when matched one of the pattern, when matched both returns `false`
|
113
|
+
* NAND(*patterns) - Product is an inverted `AND`
|
114
|
+
* NOR(*patterns) - Product is an inverted `OR`
|
115
|
+
|
116
|
+
### Best fit for RSpec's `satisfy` matcher too
|
117
|
+
|
118
|
+
All builders actually generate a `Proc (lambda)` instance.
|
119
|
+
The signature will fit for RSpec's built-in [`satisfy` matcher](https://relishapp.com/rspec/rspec-expectations/v/3-10/docs/built-in-matchers/satisfy-matcher) too.
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
RSpec.describe RSpec::Matchers::BuiltIn::Satisfy do
|
123
|
+
let(:product) { Eqq.AND(Integer, 24..42) }
|
124
|
+
|
125
|
+
it 'perfectly works' do
|
126
|
+
expect(23).not_to satisfy(&product)
|
127
|
+
expect(24).to satisfy(&product)
|
128
|
+
expect(24.0).not_to satisfy(&product)
|
129
|
+
expect(42).to satisfy(&product)
|
130
|
+
expect(42.0).not_to satisfy(&product)
|
131
|
+
expect(43).not_to satisfy(&product)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
```
|
135
|
+
|
136
|
+
### Use builders without receiver specifying
|
137
|
+
|
138
|
+
When you felt annoy to write `Eqq` in many place, some ways exist.
|
139
|
+
|
140
|
+
* `Eqq.define(&block)` - In the block scope, all builder methods can be used without receiver
|
141
|
+
* `extend Eqq::Buildable` - In the class/module, all builders can be used as class methods
|
142
|
+
* `include Eqq::Buildable` - In the class/module, all builders can be used as instance methods
|
143
|
+
|
144
|
+
### Signature
|
145
|
+
|
146
|
+
* This gem provides [ruby/rbs](https://github.com/ruby/rbs) signature file
|
147
|
+
|
35
148
|
## Links
|
36
149
|
|
37
150
|
* [Repository](https://github.com/kachick/eqq)
|
38
151
|
* [API documents](https://kachick.github.io/eqq)
|
152
|
+
|
153
|
+
## NOTE
|
154
|
+
|
155
|
+
* [`eqq` is the implementation name of `#===` in CRuby](https://github.com/ruby/ruby/blob/2a685da1fcd928530509e99f5edb4117bc377994/range.c#L1859)
|
data/lib/eqq.rb
CHANGED
@@ -2,238 +2,60 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
# Copyright (c) 2011 Kenichi Kamiya
|
5
|
-
# Forked from https://github.com/kachick/
|
5
|
+
# Forked from https://github.com/kachick/validation at 2021
|
6
6
|
|
7
|
-
|
8
|
-
def self.conditionable?(object)
|
9
|
-
case object
|
10
|
-
when Proc, Method
|
11
|
-
object.arity == 1
|
12
|
-
else
|
13
|
-
begin
|
14
|
-
object.respond_to?(:===)
|
15
|
-
rescue NoMethodError
|
16
|
-
false
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.define(&block)
|
22
|
-
module_exec(&block)
|
23
|
-
end
|
24
|
-
|
25
|
-
module_function
|
26
|
-
|
27
|
-
# A condition builder.
|
28
|
-
# @param condition1 [Proc, Method, #===]
|
29
|
-
# @param condition2 [Proc, Method, #===]
|
30
|
-
# @param conditions [Array<Proc, Method, #===>]
|
31
|
-
# @return [Proc]
|
32
|
-
# this lambda return true if match all conditions
|
33
|
-
def AND(condition1, condition2, *conditions)
|
34
|
-
->v {
|
35
|
-
[condition1, condition2, *conditions].all? { |condition| condition === v }
|
36
|
-
}
|
37
|
-
end
|
38
|
-
|
39
|
-
# A condition builder.
|
40
|
-
# @param condition1 [Proc, Method, #===]
|
41
|
-
# @param condition2 [Proc, Method, #===]
|
42
|
-
# @param conditions [Array<Proc, Method, #===>]
|
43
|
-
# @return [Proc]
|
44
|
-
def NAND(condition1, condition2, *conditions)
|
45
|
-
NOT(AND(condition1, condition2, *conditions))
|
46
|
-
end
|
47
|
-
|
48
|
-
# A condition builder.
|
49
|
-
# @param condition1 [Proc, Method, #===]
|
50
|
-
# @param condition2 [Proc, Method, #===]
|
51
|
-
# @param conditions [Array<Proc, Method, #===>]
|
52
|
-
# @return [Proc]
|
53
|
-
# this lambda return true if match a any condition
|
54
|
-
def OR(condition1, condition2, *conditions)
|
55
|
-
->v {
|
56
|
-
[condition1, condition2, *conditions].any? { |condition| condition === v }
|
57
|
-
}
|
58
|
-
end
|
59
|
-
|
60
|
-
# A condition builder.
|
61
|
-
# @param condition1 [Proc, Method, #===]
|
62
|
-
# @param condition2 [Proc, Method, #===]
|
63
|
-
# @param conditions [Array<Proc, Method, #===>]
|
64
|
-
# @return [Proc]
|
65
|
-
def NOR(condition1, condition2, *conditions)
|
66
|
-
NOT(OR(condition1, condition2, *conditions))
|
67
|
-
end
|
68
|
-
|
69
|
-
# A condition builder.
|
70
|
-
# @param condition1 [Proc, Method, #===]
|
71
|
-
# @param condition2 [Proc, Method, #===]
|
72
|
-
# @param conditions [Array<Proc, Method, #===>]
|
73
|
-
# @return [Proc]
|
74
|
-
def XOR(condition1, condition2, *conditions)
|
75
|
-
->v {
|
76
|
-
[condition1, condition2, *conditions].one? { |condition| condition === v }
|
77
|
-
}
|
78
|
-
end
|
79
|
-
|
80
|
-
# A condition builder.
|
81
|
-
# @param condition1 [Proc, Method, #===]
|
82
|
-
# @param condition2 [Proc, Method, #===]
|
83
|
-
# @param conditions [Array<Proc, Method, #===>]
|
84
|
-
# @return [Proc]
|
85
|
-
def XNOR(condition1, condition2, *conditions)
|
86
|
-
NOT(XOR(condition1, condition2, *conditions))
|
87
|
-
end
|
88
|
-
|
89
|
-
# A condition builder.
|
90
|
-
# @param condition [Proc, Method, #===]
|
91
|
-
# @return [Proc] A condition invert the original condition.
|
92
|
-
def NOT(condition)
|
93
|
-
unless Eqq.conditionable?(condition)
|
94
|
-
raise TypeError, 'wrong object for condition'
|
95
|
-
end
|
96
|
-
|
97
|
-
->v { !(condition === v) }
|
98
|
-
end
|
99
|
-
|
100
|
-
# A condition builder.
|
101
|
-
# @param obj [#==]
|
102
|
-
# @return [Proc]
|
103
|
-
# this lambda return true if a argument match under #== method
|
104
|
-
def EQ(obj)
|
105
|
-
->v { obj == v }
|
106
|
-
end
|
107
|
-
|
108
|
-
# A condition builder.
|
109
|
-
# @param obj [#equal?]
|
110
|
-
# @return [Proc]
|
111
|
-
# this lambda return true if a argument match under #equal? method
|
112
|
-
def SAME(obj)
|
113
|
-
->v { obj.equal?(v) }
|
114
|
-
end
|
115
|
-
|
116
|
-
# A condition builder.
|
117
|
-
# @param message1 [Symbol, String]
|
118
|
-
# @param messages [Array<Symbol, String>]
|
119
|
-
# @return [Proc]
|
120
|
-
# this lambda return true if a argument respond to all messages
|
121
|
-
def CAN(message1, *messages)
|
122
|
-
messages = [message1, *messages].map(&:to_sym)
|
7
|
+
require_relative 'eqq/version'
|
123
8
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
end
|
9
|
+
# Pattern objects builder
|
10
|
+
module Eqq
|
11
|
+
# Base error of this library
|
12
|
+
class Error < StandardError; end
|
128
13
|
|
129
|
-
#
|
130
|
-
|
131
|
-
# @param conditions [Array<Proc, Method, #===>]
|
132
|
-
# @return [Proc]
|
133
|
-
# this lambda return true
|
134
|
-
# if face no exception when a argument checking under all conditions
|
135
|
-
def QUIET(condition1, *conditions)
|
136
|
-
conditions = [condition1, *conditions]
|
137
|
-
unless conditions.all? { |c| Eqq.conditionable?(c) }
|
138
|
-
raise TypeError, 'wrong object for condition'
|
139
|
-
end
|
14
|
+
# Raised when found some products are invalid as a pattern object
|
15
|
+
class InvalidProductError < Error; end
|
140
16
|
|
141
|
-
|
142
|
-
|
17
|
+
class << self
|
18
|
+
def pattern?(object)
|
19
|
+
case object
|
20
|
+
when Proc, Method
|
21
|
+
object.arity == 1
|
22
|
+
else
|
143
23
|
begin
|
144
|
-
|
145
|
-
rescue
|
24
|
+
object.respond_to?(:===)
|
25
|
+
rescue NoMethodError
|
146
26
|
false
|
147
|
-
else
|
148
|
-
true
|
149
27
|
end
|
150
|
-
}
|
151
|
-
}
|
152
|
-
end
|
153
|
-
|
154
|
-
# A condition builder.
|
155
|
-
# @param exception [Exception]
|
156
|
-
# @param exceptions [Array<Exception>]
|
157
|
-
# @return [Proc]
|
158
|
-
# this lambda return true
|
159
|
-
# if catch any kindly exceptions when a argument checking in a block parameter
|
160
|
-
def RESCUE(exception, *exceptions, &condition)
|
161
|
-
exceptions = [exception, *exceptions]
|
162
|
-
raise ArgumentError unless Eqq.conditionable?(condition)
|
163
|
-
raise ArgumentError unless exceptions.all?(Exception)
|
164
|
-
|
165
|
-
->v {
|
166
|
-
begin
|
167
|
-
condition.call(v)
|
168
|
-
false
|
169
|
-
rescue *exceptions
|
170
|
-
true
|
171
|
-
rescue Exception
|
172
|
-
false
|
173
28
|
end
|
174
|
-
|
175
|
-
end
|
176
|
-
|
177
|
-
# A condition builder.
|
178
|
-
# @param exception [Exception]
|
179
|
-
# @return [Proc]
|
180
|
-
# this lambda return true
|
181
|
-
# if catch a specific exception when a argument checking in a block parameter
|
182
|
-
def CATCH(exception, &condition)
|
183
|
-
raise ArgumentError unless Eqq.conditionable?(condition)
|
184
|
-
raise ArgumentError unless exceptions.all?(Exception)
|
29
|
+
end
|
185
30
|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
err.instance_of?(exception)
|
191
|
-
else
|
192
|
-
false
|
193
|
-
end
|
194
|
-
}
|
195
|
-
end
|
31
|
+
# @deprecated Use {pattern?} instead. This will be dropped since `0.1.0`
|
32
|
+
def valid?(object)
|
33
|
+
pattern?(object)
|
34
|
+
end
|
196
35
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
# @return [Proc]
|
202
|
-
# this lambda return true
|
203
|
-
# if all included objects match all conditions
|
204
|
-
def ALL(condition1, condition2, *conditions)
|
205
|
-
condition = Eqq.AND(condition1, condition2, *conditions)
|
36
|
+
# @api private
|
37
|
+
def satisfy?(object)
|
38
|
+
(Proc === object) && object.lambda? && (object.arity == 1)
|
39
|
+
end
|
206
40
|
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
when list.respond_to?(:all?)
|
213
|
-
list
|
214
|
-
when list.respond_to?(:each)
|
215
|
-
list.each
|
216
|
-
else
|
217
|
-
return false
|
218
|
-
end
|
219
|
-
)
|
41
|
+
# @return [#===]
|
42
|
+
# @raise [InvalidProductError] if the return value is invalid as a pattern object
|
43
|
+
def define(&block)
|
44
|
+
pattern = DSLScope.new.instance_exec(&block)
|
45
|
+
raise InvalidProductError unless satisfy?(pattern)
|
220
46
|
|
221
|
-
|
222
|
-
|
47
|
+
pattern
|
48
|
+
end
|
223
49
|
end
|
50
|
+
end
|
224
51
|
|
225
|
-
|
226
|
-
# BasicObject.=== always passing
|
227
|
-
BasicObject
|
228
|
-
end
|
52
|
+
require_relative 'eqq/buildable'
|
229
53
|
|
230
|
-
|
54
|
+
module Eqq
|
55
|
+
extend Buildable
|
231
56
|
|
232
|
-
|
233
|
-
|
234
|
-
def BOOLEAN
|
235
|
-
BOOLEAN
|
57
|
+
class DSLScope
|
58
|
+
include Buildable
|
236
59
|
end
|
60
|
+
private_constant :DSLScope
|
237
61
|
end
|
238
|
-
|
239
|
-
require_relative 'eqq/version'
|
@@ -0,0 +1,292 @@
|
|
1
|
+
# coding: us-ascii
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Eqq
|
5
|
+
# Actually having definitions for the pattern builders
|
6
|
+
module Buildable
|
7
|
+
class << self
|
8
|
+
# When the inspection is failed some unexpected reasons, it will fallback to this value
|
9
|
+
# This value is not fixed as a spec, might be changed in future
|
10
|
+
INSPECTION_FALLBACK = 'UninspectableObject'
|
11
|
+
|
12
|
+
# @api private
|
13
|
+
# @return [String]
|
14
|
+
def safe_inspect_for(object)
|
15
|
+
String.try_convert(object.inspect) || INSPECTION_FALLBACK
|
16
|
+
rescue Exception
|
17
|
+
# This implementation used `RSpec::Support::ObjectFormatter::UninspectableObjectInspector` as a reference, thank you!
|
18
|
+
# ref: https://github.com/kachick/times_kachick/issues/97
|
19
|
+
singleton_class = class << object; self; end
|
20
|
+
begin
|
21
|
+
klass = singleton_class.ancestors.detect { |ancestor| !ancestor.equal?(singleton_class) }
|
22
|
+
native_object_id = '%#016x' % (object.__id__ << 1)
|
23
|
+
"#<#{klass}:#{native_object_id}>"
|
24
|
+
rescue Exception
|
25
|
+
INSPECTION_FALLBACK
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# @api private
|
30
|
+
# @return [void]
|
31
|
+
def define_inspect_on(product, name:, arguments:)
|
32
|
+
inspect = "#{name}(#{arguments.map { |argument| safe_inspect_for(argument) }.join(', ')})".freeze
|
33
|
+
product.define_singleton_method(:inspect) do
|
34
|
+
inspect
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# @api private
|
39
|
+
# @return [void]
|
40
|
+
def validate_patterns(*patterns)
|
41
|
+
invalids = patterns.reject { |pattern| Eqq.pattern?(pattern) }
|
42
|
+
invalid_inspections = invalids.map { |invalid| safe_inspect_for(invalid) }.join(', ')
|
43
|
+
raise ArgumentError, "given `#{invalid_inspections}` are invalid as pattern objects" unless invalids.empty?
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Product returns `true` when matched all patterns
|
48
|
+
#
|
49
|
+
# @param pattern1 [Proc, Method, #===]
|
50
|
+
# @param pattern2 [Proc, Method, #===]
|
51
|
+
# @param patterns [Array<Proc, Method, #===>]
|
52
|
+
# @return [Proc]
|
53
|
+
def AND(pattern1, pattern2, *patterns)
|
54
|
+
patterns = [pattern1, pattern2, *patterns].freeze
|
55
|
+
Buildable.validate_patterns(*patterns)
|
56
|
+
|
57
|
+
product = ->v {
|
58
|
+
patterns.all? { |pattern| pattern === v }
|
59
|
+
}
|
60
|
+
|
61
|
+
Buildable.define_inspect_on(product, name: 'AND', arguments: patterns)
|
62
|
+
|
63
|
+
product
|
64
|
+
end
|
65
|
+
|
66
|
+
# Product is an inverted {#AND}
|
67
|
+
#
|
68
|
+
# @param pattern1 [Proc, Method, #===]
|
69
|
+
# @param pattern2 [Proc, Method, #===]
|
70
|
+
# @param patterns [Array<Proc, Method, #===>]
|
71
|
+
# @return [Proc]
|
72
|
+
def NAND(pattern1, pattern2, *patterns)
|
73
|
+
NOT(AND(pattern1, pattern2, *patterns))
|
74
|
+
end
|
75
|
+
|
76
|
+
# Product returns `true` when matched even one pattern
|
77
|
+
#
|
78
|
+
# @param pattern1 [Proc, Method, #===]
|
79
|
+
# @param pattern2 [Proc, Method, #===]
|
80
|
+
# @param patterns [Array<Proc, Method, #===>]
|
81
|
+
# @return [Proc]
|
82
|
+
def OR(pattern1, pattern2, *patterns)
|
83
|
+
patterns = [pattern1, pattern2, *patterns].freeze
|
84
|
+
Buildable.validate_patterns(*patterns)
|
85
|
+
|
86
|
+
product = ->v {
|
87
|
+
patterns.any? { |pattern| pattern === v }
|
88
|
+
}
|
89
|
+
Buildable.define_inspect_on(product, name: 'OR', arguments: patterns)
|
90
|
+
|
91
|
+
product
|
92
|
+
end
|
93
|
+
|
94
|
+
# Product is an inverted {#OR}
|
95
|
+
#
|
96
|
+
# @param pattern1 [Proc, Method, #===]
|
97
|
+
# @param pattern2 [Proc, Method, #===]
|
98
|
+
# @param patterns [Array<Proc, Method, #===>]
|
99
|
+
# @return [Proc]
|
100
|
+
def NOR(pattern1, pattern2, *patterns)
|
101
|
+
NOT(OR(pattern1, pattern2, *patterns))
|
102
|
+
end
|
103
|
+
|
104
|
+
# Product returns `true` when matched one of the pattern, when matched both returns `false`
|
105
|
+
#
|
106
|
+
# @param pattern1 [Proc, Method, #===]
|
107
|
+
# @param pattern2 [Proc, Method, #===]
|
108
|
+
# @return [Proc]
|
109
|
+
def XOR(pattern1, pattern2)
|
110
|
+
patterns = [pattern1, pattern2].freeze
|
111
|
+
Buildable.validate_patterns(*patterns)
|
112
|
+
|
113
|
+
product = ->v {
|
114
|
+
patterns.one? { |pattern| pattern === v }
|
115
|
+
}
|
116
|
+
Buildable.define_inspect_on(product, name: 'XOR', arguments: patterns)
|
117
|
+
|
118
|
+
product
|
119
|
+
end
|
120
|
+
|
121
|
+
# Product returns `true` when not matched the pattern
|
122
|
+
#
|
123
|
+
# @param pattern [Proc, Method, #===]
|
124
|
+
# @return [Proc]
|
125
|
+
def NOT(pattern)
|
126
|
+
Buildable.validate_patterns(pattern)
|
127
|
+
|
128
|
+
product = ->v { !(pattern === v) }
|
129
|
+
|
130
|
+
Buildable.define_inspect_on(product, name: 'NOT', arguments: [pattern])
|
131
|
+
|
132
|
+
product
|
133
|
+
end
|
134
|
+
|
135
|
+
# Product returns `true` when matched with `#==`
|
136
|
+
#
|
137
|
+
# @param obj [#==]
|
138
|
+
# @return [Proc]
|
139
|
+
def EQ(obj)
|
140
|
+
product = ->v { obj == v }
|
141
|
+
Buildable.define_inspect_on(product, name: 'EQ', arguments: [obj])
|
142
|
+
product
|
143
|
+
end
|
144
|
+
|
145
|
+
# Product returns `true` when matched with `#equal?`
|
146
|
+
#
|
147
|
+
# @param obj [#equal?]
|
148
|
+
# @return [Proc]
|
149
|
+
def SAME(obj)
|
150
|
+
product = ->v { obj.equal?(v) }
|
151
|
+
Buildable.define_inspect_on(product, name: 'SAME', arguments: [obj])
|
152
|
+
product
|
153
|
+
end
|
154
|
+
|
155
|
+
# Product returns `true` when it has all of the methods (checked with `respond_to?`)
|
156
|
+
#
|
157
|
+
# @param message1 [Symbol, String, #to_sym]
|
158
|
+
# @param messages [Array<Symbol, String, #to_sym>]
|
159
|
+
# @return [Proc]
|
160
|
+
def CAN(message1, *messages)
|
161
|
+
messages = (
|
162
|
+
begin
|
163
|
+
[message1, *messages].map(&:to_sym).freeze
|
164
|
+
rescue NoMethodError
|
165
|
+
raise ArgumentError
|
166
|
+
end
|
167
|
+
)
|
168
|
+
|
169
|
+
product = ->v {
|
170
|
+
messages.all? { |message|
|
171
|
+
begin
|
172
|
+
v.respond_to?(message)
|
173
|
+
rescue NoMethodError
|
174
|
+
false
|
175
|
+
end
|
176
|
+
}
|
177
|
+
}
|
178
|
+
|
179
|
+
Buildable.define_inspect_on(product, name: 'CAN', arguments: messages)
|
180
|
+
|
181
|
+
product
|
182
|
+
end
|
183
|
+
|
184
|
+
# Product returns `true` when all patterns did not raise any exception
|
185
|
+
#
|
186
|
+
# @param pattern1 [Proc, Method, #===]
|
187
|
+
# @param patterns [Array<Proc, Method, #===>]
|
188
|
+
# @return [Proc]
|
189
|
+
def QUIET(pattern1, *patterns)
|
190
|
+
patterns = [pattern1, *patterns].freeze
|
191
|
+
Buildable.validate_patterns(*patterns)
|
192
|
+
|
193
|
+
product = ->v {
|
194
|
+
patterns.all? { |pattern|
|
195
|
+
begin
|
196
|
+
pattern === v
|
197
|
+
rescue Exception
|
198
|
+
false
|
199
|
+
else
|
200
|
+
true
|
201
|
+
end
|
202
|
+
}
|
203
|
+
}
|
204
|
+
|
205
|
+
Buildable.define_inspect_on(product, name: 'QUIET', arguments: patterns)
|
206
|
+
|
207
|
+
product
|
208
|
+
end
|
209
|
+
|
210
|
+
# Product returns `true` when the pattern raises the exception
|
211
|
+
#
|
212
|
+
# @param mod [Module]
|
213
|
+
# @param pattern [Proc, Method, #===]
|
214
|
+
# @return [Proc]
|
215
|
+
def RESCUE(mod, pattern)
|
216
|
+
Buildable.validate_patterns(pattern)
|
217
|
+
raise ArgumentError unless Module === mod
|
218
|
+
|
219
|
+
product = ->v {
|
220
|
+
begin
|
221
|
+
pattern === v
|
222
|
+
false
|
223
|
+
rescue mod
|
224
|
+
true
|
225
|
+
rescue Exception
|
226
|
+
false
|
227
|
+
end
|
228
|
+
}
|
229
|
+
|
230
|
+
Buildable.define_inspect_on(product, name: 'RESCUE', arguments: [mod, pattern])
|
231
|
+
|
232
|
+
product
|
233
|
+
end
|
234
|
+
|
235
|
+
# Basically provided for Enumerable
|
236
|
+
#
|
237
|
+
# @param name [Symbol, String, #to_sym]
|
238
|
+
# @param pattern [Proc, Method, #===]
|
239
|
+
# @return [Proc]
|
240
|
+
def SEND(name, pattern)
|
241
|
+
name = (
|
242
|
+
begin
|
243
|
+
name.to_sym
|
244
|
+
rescue NoMethodError
|
245
|
+
raise ArgumentError
|
246
|
+
end
|
247
|
+
)
|
248
|
+
Buildable.validate_patterns(pattern)
|
249
|
+
|
250
|
+
product = ->v {
|
251
|
+
v.__send__(name, pattern)
|
252
|
+
}
|
253
|
+
|
254
|
+
Buildable.define_inspect_on(product, name: 'SEND', arguments: [name, pattern])
|
255
|
+
|
256
|
+
product
|
257
|
+
end
|
258
|
+
|
259
|
+
ANYTHING = ->_v { true }
|
260
|
+
define_inspect_on(ANYTHING, name: 'ANYTHING', arguments: [])
|
261
|
+
private_constant :ANYTHING
|
262
|
+
|
263
|
+
# Product returns `true`, always `true`
|
264
|
+
#
|
265
|
+
# @return [Proc]
|
266
|
+
def ANYTHING
|
267
|
+
ANYTHING
|
268
|
+
end
|
269
|
+
|
270
|
+
NEVER = ->_v { false }
|
271
|
+
define_inspect_on(NEVER, name: 'NEVER', arguments: [])
|
272
|
+
private_constant :NEVER
|
273
|
+
|
274
|
+
# Product returns `false`, always `false`
|
275
|
+
#
|
276
|
+
# @return [Proc]
|
277
|
+
def NEVER
|
278
|
+
NEVER
|
279
|
+
end
|
280
|
+
|
281
|
+
BOOLEAN = ->v { true.equal?(v) || false.equal?(v) }
|
282
|
+
define_inspect_on(BOOLEAN, name: 'BOOLEAN', arguments: [])
|
283
|
+
private_constant :BOOLEAN
|
284
|
+
|
285
|
+
# Product returns `true` when matched to `true` or `false`
|
286
|
+
#
|
287
|
+
# @return [Proc]
|
288
|
+
def BOOLEAN
|
289
|
+
BOOLEAN
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
data/lib/eqq/version.rb
CHANGED
data/sig/eqq.rbs
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
# Pattern objects builder
|
2
|
+
module Eqq
|
3
|
+
interface _Patternable
|
4
|
+
def ===: (untyped object) -> bool
|
5
|
+
end
|
6
|
+
|
7
|
+
interface _ToSym
|
8
|
+
def to_sym: -> Symbol
|
9
|
+
end
|
10
|
+
|
11
|
+
interface _Inspectable
|
12
|
+
def inspect: () -> String
|
13
|
+
end
|
14
|
+
|
15
|
+
module Buildable
|
16
|
+
type patternable_lambda = ^(untyped object) -> bool
|
17
|
+
type product = patternable_lambda & _Inspectable
|
18
|
+
|
19
|
+
# A private constant. Should not be used in your code.
|
20
|
+
ANYTHING: product
|
21
|
+
|
22
|
+
# A private constant. Should not be used in your code.
|
23
|
+
NEVER: product
|
24
|
+
|
25
|
+
# A private constant. Should not be used in your code.
|
26
|
+
BOOLEAN: product
|
27
|
+
|
28
|
+
# A private API. Should not be used in your code.
|
29
|
+
def self.safe_inspect_for: (untyped object)-> String
|
30
|
+
|
31
|
+
# A private API. Should not be used in your code.
|
32
|
+
def self.define_inspect_on: (patternable_lambda product, name: String, arguments: Array[untyped])-> void
|
33
|
+
|
34
|
+
# A private API. Should not be used in your code.
|
35
|
+
def self.validate_patterns: (*untyped) -> void
|
36
|
+
|
37
|
+
# Product returns `true` when matched even one pattern
|
38
|
+
def OR: (_Patternable, _Patternable, *_Patternable) -> product
|
39
|
+
|
40
|
+
# Product returns `true` when matched all patterns
|
41
|
+
def AND: (_Patternable, _Patternable, *_Patternable) -> product
|
42
|
+
|
43
|
+
# Product is an inverted `AND`
|
44
|
+
def NAND: (_Patternable, _Patternable, *_Patternable) -> product
|
45
|
+
|
46
|
+
# Product is an inverted `OR`
|
47
|
+
def NOR: (_Patternable, _Patternable, *_Patternable) -> product
|
48
|
+
|
49
|
+
# Product returns `true` when matched one of the pattern, when matched both returns `false`
|
50
|
+
def XOR: (_Patternable, _Patternable) -> product
|
51
|
+
|
52
|
+
# Product returns `true` when not matched the pattern
|
53
|
+
def NOT: (_Patternable) -> product
|
54
|
+
|
55
|
+
# Product returns `true` when matched with `#==`
|
56
|
+
def EQ: (untyped object) -> product
|
57
|
+
|
58
|
+
# Product returns `true` when matched with `#equal?`
|
59
|
+
def SAME: (untyped object) -> product
|
60
|
+
|
61
|
+
# Product returns `true` when it has all of the methods (checked with `respond_to?`)
|
62
|
+
def CAN: (_ToSym, *_ToSym) -> product
|
63
|
+
|
64
|
+
# Product returns `true` when the pattern raises the exception
|
65
|
+
def RESCUE: (Module, _Patternable) -> product
|
66
|
+
|
67
|
+
# Product returns `true` when all patterns did not raise any exception
|
68
|
+
def QUIET: (_Patternable, *_Patternable) -> product
|
69
|
+
|
70
|
+
# Basically provided for Enumerable
|
71
|
+
def SEND: (Symbol | String name, _Patternable) -> product
|
72
|
+
|
73
|
+
# Product returns `true`, always `true`
|
74
|
+
def ANYTHING: () -> product
|
75
|
+
|
76
|
+
# Product returns `false`, always `false`
|
77
|
+
def NEVER: () -> product
|
78
|
+
|
79
|
+
# Product returns `true` when matched to `true` or `false`
|
80
|
+
def BOOLEAN: () -> product
|
81
|
+
end
|
82
|
+
|
83
|
+
extend Buildable
|
84
|
+
|
85
|
+
# Base error of this library
|
86
|
+
class Error < StandardError
|
87
|
+
end
|
88
|
+
|
89
|
+
# Raised when found some products are invalid as a pattern object
|
90
|
+
class InvalidProductError < Error
|
91
|
+
end
|
92
|
+
|
93
|
+
# A private API. Should not be used in your code.
|
94
|
+
class DSLScope
|
95
|
+
include Buildable
|
96
|
+
end
|
97
|
+
|
98
|
+
VERSION: String
|
99
|
+
|
100
|
+
# Returns `true` when given object has patternable signature
|
101
|
+
def self.pattern?: (untyped object) -> bool
|
102
|
+
|
103
|
+
# Alias of `pattern?`. But deperecated. Do not use in your code anymore.
|
104
|
+
def self.valid?: (untyped object) -> bool
|
105
|
+
|
106
|
+
# Returns `true` when given object has correct signature as a product of builders
|
107
|
+
# Basically this is a private API. Should not be used in your code.
|
108
|
+
def self.satisfy?: (untyped object) -> bool
|
109
|
+
|
110
|
+
# In the block scope, all builder methods can be used without receiver
|
111
|
+
def self.define: { () -> _Patternable } -> _Patternable
|
112
|
+
end
|
metadata
CHANGED
@@ -1,230 +1,23 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eqq
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kenichi Kamiya
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-06-
|
12
|
-
dependencies:
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: '4.0'
|
23
|
-
type: :development
|
24
|
-
prerelease: false
|
25
|
-
version_requirements: !ruby/object:Gem::Requirement
|
26
|
-
requirements:
|
27
|
-
- - ">="
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: 3.4.1
|
30
|
-
- - "<"
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: '4.0'
|
33
|
-
- !ruby/object:Gem::Dependency
|
34
|
-
name: irb
|
35
|
-
requirement: !ruby/object:Gem::Requirement
|
36
|
-
requirements:
|
37
|
-
- - ">="
|
38
|
-
- !ruby/object:Gem::Version
|
39
|
-
version: 1.3.5
|
40
|
-
- - "<"
|
41
|
-
- !ruby/object:Gem::Version
|
42
|
-
version: '2.0'
|
43
|
-
type: :development
|
44
|
-
prerelease: false
|
45
|
-
version_requirements: !ruby/object:Gem::Requirement
|
46
|
-
requirements:
|
47
|
-
- - ">="
|
48
|
-
- !ruby/object:Gem::Version
|
49
|
-
version: 1.3.5
|
50
|
-
- - "<"
|
51
|
-
- !ruby/object:Gem::Version
|
52
|
-
version: '2.0'
|
53
|
-
- !ruby/object:Gem::Dependency
|
54
|
-
name: irb-power_assert
|
55
|
-
requirement: !ruby/object:Gem::Requirement
|
56
|
-
requirements:
|
57
|
-
- - '='
|
58
|
-
- !ruby/object:Gem::Version
|
59
|
-
version: 0.0.2
|
60
|
-
type: :development
|
61
|
-
prerelease: false
|
62
|
-
version_requirements: !ruby/object:Gem::Requirement
|
63
|
-
requirements:
|
64
|
-
- - '='
|
65
|
-
- !ruby/object:Gem::Version
|
66
|
-
version: 0.0.2
|
67
|
-
- !ruby/object:Gem::Dependency
|
68
|
-
name: warning
|
69
|
-
requirement: !ruby/object:Gem::Requirement
|
70
|
-
requirements:
|
71
|
-
- - ">="
|
72
|
-
- !ruby/object:Gem::Version
|
73
|
-
version: 1.2.0
|
74
|
-
- - "<"
|
75
|
-
- !ruby/object:Gem::Version
|
76
|
-
version: '2.0'
|
77
|
-
type: :development
|
78
|
-
prerelease: false
|
79
|
-
version_requirements: !ruby/object:Gem::Requirement
|
80
|
-
requirements:
|
81
|
-
- - ">="
|
82
|
-
- !ruby/object:Gem::Version
|
83
|
-
version: 1.2.0
|
84
|
-
- - "<"
|
85
|
-
- !ruby/object:Gem::Version
|
86
|
-
version: '2.0'
|
87
|
-
- !ruby/object:Gem::Dependency
|
88
|
-
name: rake
|
89
|
-
requirement: !ruby/object:Gem::Requirement
|
90
|
-
requirements:
|
91
|
-
- - ">="
|
92
|
-
- !ruby/object:Gem::Version
|
93
|
-
version: 13.0.3
|
94
|
-
- - "<"
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '20.0'
|
97
|
-
type: :development
|
98
|
-
prerelease: false
|
99
|
-
version_requirements: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - ">="
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: 13.0.3
|
104
|
-
- - "<"
|
105
|
-
- !ruby/object:Gem::Version
|
106
|
-
version: '20.0'
|
107
|
-
- !ruby/object:Gem::Dependency
|
108
|
-
name: yard
|
109
|
-
requirement: !ruby/object:Gem::Requirement
|
110
|
-
requirements:
|
111
|
-
- - ">="
|
112
|
-
- !ruby/object:Gem::Version
|
113
|
-
version: 0.9.26
|
114
|
-
- - "<"
|
115
|
-
- !ruby/object:Gem::Version
|
116
|
-
version: '2'
|
117
|
-
type: :development
|
118
|
-
prerelease: false
|
119
|
-
version_requirements: !ruby/object:Gem::Requirement
|
120
|
-
requirements:
|
121
|
-
- - ">="
|
122
|
-
- !ruby/object:Gem::Version
|
123
|
-
version: 0.9.26
|
124
|
-
- - "<"
|
125
|
-
- !ruby/object:Gem::Version
|
126
|
-
version: '2'
|
127
|
-
- !ruby/object:Gem::Dependency
|
128
|
-
name: rubocop
|
129
|
-
requirement: !ruby/object:Gem::Requirement
|
130
|
-
requirements:
|
131
|
-
- - ">="
|
132
|
-
- !ruby/object:Gem::Version
|
133
|
-
version: 1.15.0
|
134
|
-
- - "<"
|
135
|
-
- !ruby/object:Gem::Version
|
136
|
-
version: 1.16.0
|
137
|
-
type: :development
|
138
|
-
prerelease: false
|
139
|
-
version_requirements: !ruby/object:Gem::Requirement
|
140
|
-
requirements:
|
141
|
-
- - ">="
|
142
|
-
- !ruby/object:Gem::Version
|
143
|
-
version: 1.15.0
|
144
|
-
- - "<"
|
145
|
-
- !ruby/object:Gem::Version
|
146
|
-
version: 1.16.0
|
147
|
-
- !ruby/object:Gem::Dependency
|
148
|
-
name: rubocop-rake
|
149
|
-
requirement: !ruby/object:Gem::Requirement
|
150
|
-
requirements:
|
151
|
-
- - ">="
|
152
|
-
- !ruby/object:Gem::Version
|
153
|
-
version: 0.5.1
|
154
|
-
- - "<"
|
155
|
-
- !ruby/object:Gem::Version
|
156
|
-
version: 0.6.0
|
157
|
-
type: :development
|
158
|
-
prerelease: false
|
159
|
-
version_requirements: !ruby/object:Gem::Requirement
|
160
|
-
requirements:
|
161
|
-
- - ">="
|
162
|
-
- !ruby/object:Gem::Version
|
163
|
-
version: 0.5.1
|
164
|
-
- - "<"
|
165
|
-
- !ruby/object:Gem::Version
|
166
|
-
version: 0.6.0
|
167
|
-
- !ruby/object:Gem::Dependency
|
168
|
-
name: rubocop-performance
|
169
|
-
requirement: !ruby/object:Gem::Requirement
|
170
|
-
requirements:
|
171
|
-
- - ">="
|
172
|
-
- !ruby/object:Gem::Version
|
173
|
-
version: 1.11.3
|
174
|
-
- - "<"
|
175
|
-
- !ruby/object:Gem::Version
|
176
|
-
version: 1.12.0
|
177
|
-
type: :development
|
178
|
-
prerelease: false
|
179
|
-
version_requirements: !ruby/object:Gem::Requirement
|
180
|
-
requirements:
|
181
|
-
- - ">="
|
182
|
-
- !ruby/object:Gem::Version
|
183
|
-
version: 1.11.3
|
184
|
-
- - "<"
|
185
|
-
- !ruby/object:Gem::Version
|
186
|
-
version: 1.12.0
|
187
|
-
- !ruby/object:Gem::Dependency
|
188
|
-
name: rubocop-rubycw
|
189
|
-
requirement: !ruby/object:Gem::Requirement
|
190
|
-
requirements:
|
191
|
-
- - ">="
|
192
|
-
- !ruby/object:Gem::Version
|
193
|
-
version: 0.1.6
|
194
|
-
- - "<"
|
195
|
-
- !ruby/object:Gem::Version
|
196
|
-
version: 0.2.0
|
197
|
-
type: :development
|
198
|
-
prerelease: false
|
199
|
-
version_requirements: !ruby/object:Gem::Requirement
|
200
|
-
requirements:
|
201
|
-
- - ">="
|
202
|
-
- !ruby/object:Gem::Version
|
203
|
-
version: 0.1.6
|
204
|
-
- - "<"
|
205
|
-
- !ruby/object:Gem::Version
|
206
|
-
version: 0.2.0
|
207
|
-
- !ruby/object:Gem::Dependency
|
208
|
-
name: rubocop-md
|
209
|
-
requirement: !ruby/object:Gem::Requirement
|
210
|
-
requirements:
|
211
|
-
- - ">="
|
212
|
-
- !ruby/object:Gem::Version
|
213
|
-
version: 1.0.1
|
214
|
-
- - "<"
|
215
|
-
- !ruby/object:Gem::Version
|
216
|
-
version: 2.0.0
|
217
|
-
type: :development
|
218
|
-
prerelease: false
|
219
|
-
version_requirements: !ruby/object:Gem::Requirement
|
220
|
-
requirements:
|
221
|
-
- - ">="
|
222
|
-
- !ruby/object:Gem::Version
|
223
|
-
version: 1.0.1
|
224
|
-
- - "<"
|
225
|
-
- !ruby/object:Gem::Version
|
226
|
-
version: 2.0.0
|
227
|
-
description: " [4.2, 42, 42.0, 420].grep(Eqq.AND(Integer, 20..50)) #=> [42]\n"
|
11
|
+
date: 2021-06-06 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: |2
|
14
|
+
Pattern objects builder.
|
15
|
+
|
16
|
+
All products can be used as `pattern === something`.
|
17
|
+
|
18
|
+
All products can be mixed with other products as a parts.
|
19
|
+
|
20
|
+
Reuse as you wish!
|
228
21
|
email:
|
229
22
|
- kachick1+ruby@gmail.com
|
230
23
|
executables: []
|
@@ -234,7 +27,9 @@ files:
|
|
234
27
|
- MIT-LICENSE.txt
|
235
28
|
- README.md
|
236
29
|
- lib/eqq.rb
|
30
|
+
- lib/eqq/buildable.rb
|
237
31
|
- lib/eqq/version.rb
|
32
|
+
- sig/eqq.rbs
|
238
33
|
homepage: https://github.com/kachick/eqq
|
239
34
|
licenses:
|
240
35
|
- MIT
|
@@ -251,7 +46,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
251
46
|
requirements:
|
252
47
|
- - ">="
|
253
48
|
- !ruby/object:Gem::Version
|
254
|
-
version: 2.
|
49
|
+
version: 2.6.0
|
255
50
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
256
51
|
requirements:
|
257
52
|
- - ">="
|
@@ -261,5 +56,5 @@ requirements: []
|
|
261
56
|
rubygems_version: 3.2.15
|
262
57
|
signing_key:
|
263
58
|
specification_version: 4
|
264
|
-
summary: Pattern objects builder
|
59
|
+
summary: Pattern objects builder
|
265
60
|
test_files: []
|