module Eqq::Buildable
Actually having definitions for the pattern builders
Constants
- EQQ_BUILTIN_ANYTHING
- EQQ_BUILTIN_BOOLEAN
- EQQ_BUILTIN_NEVER
- EQQ_BUILTIN_NIL
- 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
Public Class Methods
@api private @return [void]
# 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
@api private @return [String]
# 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
@api private @return [void]
# 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
Public Instance Methods
Product returns `true` when matched all patterns
@param pattern1 [Proc, Method, ===] @param pattern2 [Proc, Method, ===] @param patterns [Array<Proc, Method, ===>] @return [Proc]
# 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
Product returns `true`, always `true`
@return [Proc]
# File lib/eqq/buildable.rb, line 265 def ANYTHING EQQ_BUILTIN_ANYTHING end
Product returns `true` when matched to `true` or `false`
@return [Proc]
# File lib/eqq/buildable.rb, line 285 def BOOLEAN EQQ_BUILTIN_BOOLEAN end
Product returns `true` when it has all of the methods (checked with `respond_to?`)
@param message1 [Symbol, String, to_sym] @param messages [Array<Symbol, String, to_sym>] @return [Proc]
# File lib/eqq/buildable.rb, line 160 def CAN(message1, *messages) messages = ( begin [message1, *messages].map(&:to_sym).freeze rescue NoMethodError raise ArgumentError end ) product = ->v { messages.all? { |message| begin v.respond_to?(message) rescue NoMethodError false end } } Buildable.define_inspect_on(product, name: 'CAN', arguments: messages) product end
Product returns `true` when matched with `#==`
@param obj [#==] @return [Proc]
# 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
Product is an inverted {#AND}
@param pattern1 [Proc, Method, ===] @param pattern2 [Proc, Method, ===] @param patterns [Array<Proc, Method, ===>] @return [Proc]
# File lib/eqq/buildable.rb, line 72 def NAND(pattern1, pattern2, *patterns) NOT(AND(pattern1, pattern2, *patterns)) end
Product returns `false`, always `false`
@return [Proc]
# File lib/eqq/buildable.rb, line 275 def NEVER EQQ_BUILTIN_NEVER end
Product returns `true` when matched to `nil` (Not consider `nil?`)
@return [Proc]
# File lib/eqq/buildable.rb, line 295 def NIL EQQ_BUILTIN_NIL end
Product is an inverted {#OR}
@param pattern1 [Proc, Method, ===] @param pattern2 [Proc, Method, ===] @param patterns [Array<Proc, Method, ===>] @return [Proc]
# File lib/eqq/buildable.rb, line 100 def NOR(pattern1, pattern2, *patterns) NOT(OR(pattern1, pattern2, *patterns)) end
Product returns `true` when not matched the pattern
@param pattern [Proc, Method, ===] @return [Proc]
# 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
Product returns `true` when matched even one pattern
@param pattern1 [Proc, Method, ===] @param pattern2 [Proc, Method, ===] @param patterns [Array<Proc, Method, ===>] @return [Proc]
# 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
Product returns `true` when all patterns did not raise any exception
@param pattern1 [Proc, Method, ===] @param patterns [Array<Proc, Method, ===>] @return [Proc]
# 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
Product returns `true` when the pattern raises the exception
@param mod [Module] @param pattern [Proc, Method, ===] @return [Proc]
# 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
Product returns `true` when matched with `#equal?`
@param obj [#equal?] @return [Proc]
# 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
Basically provided for Enumerable
@param name [Symbol, String, to_sym] @param pattern [Proc, Method, ===] @return [Proc]
# 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
Product returns `true` when matched one of the pattern, when matched both returns `false`
@param pattern1 [Proc, Method, ===] @param pattern2 [Proc, Method, ===] @return [Proc]
# 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