Module: Eqq::Buildable
- Included in:
- Eqq
- Defined in:
- lib/eqq/buildable.rb
Overview
Actually having definitions for the pattern builders
Constant Summary collapse
- INSPECTION_FALLBACK =
When the inspection is failed some unexpected reasons, it will fallback to this value This value is not fixed as a spec, might be changed in future
'UninspectableObject'
Class Method Summary collapse
- .define_inspect_on(product, name:, arguments:) ⇒ void private
- .safe_inspect_for(object) ⇒ String private
- .validate_patterns(*patterns) ⇒ void private
Instance Method Summary collapse
-
#AND(pattern1, pattern2, *patterns) ⇒ Proc
Product returns ‘true` when matched all patterns.
-
#ANYTHING ⇒ Proc
Product returns ‘true`, always `true`.
-
#BOOLEAN ⇒ Proc
Product returns ‘true` when matched to `true` or `false`.
-
#CAN(message1, *messages) ⇒ Proc
Product returns ‘true` when it has all of the methods (checked with `respond_to?`).
-
#EQ(obj) ⇒ Proc
Product returns ‘true` when matched with `#==`.
-
#NAND(pattern1, pattern2, *patterns) ⇒ Proc
Product is an inverted #AND.
-
#NEVER ⇒ Proc
Product returns ‘false`, always `false`.
-
#NIL ⇒ Proc
Product returns ‘true` when matched to `nil` (Not consider `nil?`).
-
#NOR(pattern1, pattern2, *patterns) ⇒ Proc
Product is an inverted #OR.
-
#NOT(pattern) ⇒ Proc
Product returns ‘true` when not matched the pattern.
-
#OR(pattern1, pattern2, *patterns) ⇒ Proc
Product returns ‘true` when matched even one pattern.
-
#QUIET(pattern1, *patterns) ⇒ Proc
Product returns ‘true` when all patterns did not raise any exception.
-
#RESCUE(mod, pattern) ⇒ Proc
Product returns ‘true` when the pattern raises the exception.
-
#SAME(obj) ⇒ Proc
Product returns ‘true` when matched with `#equal?`.
-
#SEND(name, pattern) ⇒ Proc
Basically provided for Enumerable.
-
#XOR(pattern1, pattern2) ⇒ Proc
Product returns ‘true` when matched one of the pattern, when matched both returns `false`.
Class Method Details
.define_inspect_on(product, name:, arguments:) ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
31 32 33 34 35 36 |
# File 'lib/eqq/buildable.rb', line 31 def define_inspect_on(product, name:, arguments:) inspect = "#{name}(#{arguments.map { |argument| safe_inspect_for(argument) }.join(', ')})".freeze product.define_singleton_method(:inspect) do inspect end end |
.safe_inspect_for(object) ⇒ String
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/eqq/buildable.rb', line 14 def safe_inspect_for(object) String.try_convert(object.inspect) || INSPECTION_FALLBACK rescue Exception # This implementation used `RSpec::Support::ObjectFormatter::UninspectableObjectInspector` as a reference, thank you! # ref: https://github.com/kachick/times_kachick/issues/97 singleton_class = class << object; self; end begin klass = singleton_class.ancestors.detect { |ancestor| !ancestor.equal?(singleton_class) } native_object_id = '%#016x' % (object.__id__ << 1) "#<#{klass}:#{native_object_id}>" rescue Exception INSPECTION_FALLBACK end end |
.validate_patterns(*patterns) ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
40 41 42 43 44 |
# File 'lib/eqq/buildable.rb', line 40 def validate_patterns(*patterns) invalids = patterns.reject { |pattern| Eqq.pattern?(pattern) } invalid_inspections = invalids.map { |invalid| safe_inspect_for(invalid) }.join(', ') raise ArgumentError, "given `#{invalid_inspections}` are invalid as pattern objects" unless invalids.empty? end |
Instance Method Details
#AND(pattern1, pattern2, *patterns) ⇒ Proc
Product returns ‘true` when matched all patterns
53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/eqq/buildable.rb', line 53 def AND(pattern1, pattern2, *patterns) patterns = [pattern1, pattern2, *patterns].freeze Buildable.validate_patterns(*patterns) product = ->v { patterns.all? { |pattern| pattern === v } } Buildable.define_inspect_on(product, name: 'AND', arguments: patterns) product end |
#ANYTHING ⇒ Proc
Product returns ‘true`, always `true`
265 266 267 |
# File 'lib/eqq/buildable.rb', line 265 def ANYTHING EQQ_BUILTIN_ANYTHING end |
#BOOLEAN ⇒ Proc
Product returns ‘true` when matched to `true` or `false`
285 286 287 |
# File 'lib/eqq/buildable.rb', line 285 def BOOLEAN EQQ_BUILTIN_BOOLEAN end |
#CAN(message1, *messages) ⇒ Proc
Product returns ‘true` when it has all of the methods (checked with `respond_to?`)
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/eqq/buildable.rb', line 160 def CAN(, *) = ( begin [, *].map(&:to_sym).freeze rescue NoMethodError raise ArgumentError end ) product = ->v { .all? { || begin v.respond_to?() rescue NoMethodError false end } } Buildable.define_inspect_on(product, name: 'CAN', arguments: ) product end |
#EQ(obj) ⇒ Proc
Product returns ‘true` when matched with `#==`
139 140 141 142 143 |
# File 'lib/eqq/buildable.rb', line 139 def EQ(obj) product = ->v { obj == v } Buildable.define_inspect_on(product, name: 'EQ', arguments: [obj]) product end |
#NAND(pattern1, pattern2, *patterns) ⇒ Proc
Product is an inverted #AND
72 73 74 |
# File 'lib/eqq/buildable.rb', line 72 def NAND(pattern1, pattern2, *patterns) NOT(AND(pattern1, pattern2, *patterns)) end |
#NEVER ⇒ Proc
Product returns ‘false`, always `false`
275 276 277 |
# File 'lib/eqq/buildable.rb', line 275 def NEVER EQQ_BUILTIN_NEVER end |
#NIL ⇒ Proc
Product returns ‘true` when matched to `nil` (Not consider `nil?`)
295 296 297 |
# File 'lib/eqq/buildable.rb', line 295 def NIL EQQ_BUILTIN_NIL end |
#NOR(pattern1, pattern2, *patterns) ⇒ Proc
Product is an inverted #OR
100 101 102 |
# File 'lib/eqq/buildable.rb', line 100 def NOR(pattern1, pattern2, *patterns) NOT(OR(pattern1, pattern2, *patterns)) end |
#NOT(pattern) ⇒ Proc
Product returns ‘true` when not matched the pattern
125 126 127 128 129 130 131 132 133 |
# File 'lib/eqq/buildable.rb', line 125 def NOT(pattern) Buildable.validate_patterns(pattern) product = ->v { !(pattern === v) } Buildable.define_inspect_on(product, name: 'NOT', arguments: [pattern]) product end |
#OR(pattern1, pattern2, *patterns) ⇒ Proc
Product returns ‘true` when matched even one pattern
82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/eqq/buildable.rb', line 82 def OR(pattern1, pattern2, *patterns) patterns = [pattern1, pattern2, *patterns].freeze Buildable.validate_patterns(*patterns) product = ->v { patterns.any? { |pattern| pattern === v } } Buildable.define_inspect_on(product, name: 'OR', arguments: patterns) product end |
#QUIET(pattern1, *patterns) ⇒ Proc
Product returns ‘true` when all patterns did not raise any exception
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/eqq/buildable.rb', line 189 def QUIET(pattern1, *patterns) patterns = [pattern1, *patterns].freeze Buildable.validate_patterns(*patterns) product = ->v { patterns.all? { |pattern| begin pattern === v rescue Exception false else true end } } Buildable.define_inspect_on(product, name: 'QUIET', arguments: patterns) product end |
#RESCUE(mod, pattern) ⇒ Proc
Product returns ‘true` when the pattern raises the exception
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
# File 'lib/eqq/buildable.rb', line 215 def RESCUE(mod, pattern) Buildable.validate_patterns(pattern) raise ArgumentError unless Module === mod product = ->v { begin pattern === v false rescue mod true rescue Exception false end } Buildable.define_inspect_on(product, name: 'RESCUE', arguments: [mod, pattern]) product end |
#SAME(obj) ⇒ Proc
Product returns ‘true` when matched with `#equal?`
149 150 151 152 153 |
# File 'lib/eqq/buildable.rb', line 149 def SAME(obj) product = ->v { obj.equal?(v) } Buildable.define_inspect_on(product, name: 'SAME', arguments: [obj]) product end |
#SEND(name, pattern) ⇒ Proc
Basically provided for Enumerable
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 |
# File 'lib/eqq/buildable.rb', line 240 def SEND(name, pattern) name = ( begin name.to_sym rescue NoMethodError raise ArgumentError end ) Buildable.validate_patterns(pattern) product = ->v { v.__send__(name, pattern) } Buildable.define_inspect_on(product, name: 'SEND', arguments: [name, pattern]) product end |
#XOR(pattern1, pattern2) ⇒ Proc
Product returns ‘true` when matched one of the pattern, when matched both returns `false`
109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/eqq/buildable.rb', line 109 def XOR(pattern1, pattern2) patterns = [pattern1, pattern2].freeze Buildable.validate_patterns(*patterns) product = ->v { patterns.one? { |pattern| pattern === v } } Buildable.define_inspect_on(product, name: 'XOR', arguments: patterns) product end |