class Dry::Matcher

@see dry-rb.org/gems/dry-matcher

Constants

EitherMatcher
NonExhaustiveMatchError
RUBY2_KEYWORDS
ResultMatcher

Built-in {Matcher} ready to use with `Result` or `Try` monads from [dry-monads](/gems/dry-monads) or any other compatible gems.

Provides {Case}s for two matchers:

  • `:success` matches `Dry::Monads::Result::Success` and `Dry::Monads::Try::Value` (or any other monad that responds to `#to_result` returning result monad that is `#success?`)

  • `:failure` matches `Dry::Monads::Result::Failure` and `Dry::Monads::Try::Error` (or any other monad that responds to `#to_result` returning result monad that is `#failure?`)

@return [Dry::Matcher]

@example Usage with `dry-monads`

require 'dry/monads/result'
require 'dry/matcher/result_matcher'

value = Dry::Monads::Result::Success.new('success!')

Dry::Matcher::ResultMatcher.(value) do |m|
  m.success do |v|
    "Yay: #{v}"
  end

  m.failure do |v|
    "Boo: #{v}"
  end
end #=> "Yay: success!"

@example Usage with custom monad

require 'dry/matcher/result_matcher'

class CustomBooleanMonad
  def initialize(value); @value = value; end
  attr_reader :value
  alias_method :success?, :value
  def failure?; !success?; end
  def to_result; self; end
end

value = CustomBooleanMonad.new(nil)

Dry::Matcher::ResultMatcher.(value) do |m|
  m.success { |v| "#{v.inspect} is truthy" }
  m.failure { |v| "#{v.inspect} is falsey" }
end # => "nil is falsey"

@example Usage with error codes

value = Dry::Monads::Result::Failure.new([:invalid, :reasons])

Dry::Matcher::ResultMatcher.(value) do |m|
  m.success do |v|
    "Yay: #{v}"
  end

  m.failure(:not_found) do
    "No such thing"
  end

  m.failure(:invalid) do |_code, errors|
    "Cannot be done: #{errors.inspect}"
  end
end #=> "Cannot be done: :reasons"
VERSION

Attributes

cases[R]

@return [Hash{Symbol => Case}]

Public Class Methods

for(*match_methods, with:) click to toggle source

Generates a module containing pattern matching for methods listed in `match_methods` argument with behavior defined by `with` matcher

@param [<Symbol>] match_methods @param [Dry::Matcher] with @return [Module]

@example Usage with `dry-monads`

class MonadicOperation
  include Dry::Matcher.for(:call, with: Dry::Matcher::ResultMatcher)

  def call
    Dry::Monads::Result::Success.new('Success')
  end
end

operation = MonadicOperation.new

operation.call do |m|
  m.success { |v| "#{v} was successful!"}
  m.failure { |v| "#{v} has failed!"}
end #=> "Success was successful"
Calls superclass method
# File lib/dry/matcher.rb, line 36
def self.for(*match_methods, with:)
  matcher = with

  matchers_mod = Module.new do
    match_methods.each do |match_method|
      define_method(match_method) do |*args, &block|
        result = super(*args)

        if block
          matcher.(result, &block)
        else
          result
        end
      end
      ruby2_keywords(match_method) if RUBY2_KEYWORDS
    end
  end

  Module.new do
    const_set :Matchers, matchers_mod

    def self.included(klass)
      klass.prepend const_get(:Matchers)
    end
  end
end
included(klass) click to toggle source
# File lib/dry/matcher.rb, line 57
def self.included(klass)
  klass.prepend const_get(:Matchers)
end
new(cases = {}) click to toggle source

@param [Hash{Symbol => Case}] cases

# File lib/dry/matcher.rb, line 67
def initialize(cases = {})
  @cases = cases
end

Public Instance Methods

call(result, &block) click to toggle source

Evaluate {#cases}' matchers and returns a result of block given to corresponding case matcher

@param [Object] result value that would be tested for matches with given {#cases} @param [Object] block @yieldparam [Evaluator] m @return [Object] value returned from the block given to method called

after matched pattern

@example Usage with `dry-monads`

require 'dry/monads/result'
require 'dry/matcher/result_matcher'

value = Dry::Monads::Result::Failure.new('failure!')

Dry::Matcher::ResultMatcher.(value) do |m|
  m.success { |v| "Yay: #{v}" }
  m.failure { |v| "Boo: #{v}" }
end #=> "Boo: failure!"
# File lib/dry/matcher.rb, line 90
def call(result, &block)
  Evaluator.new(result, cases).call(&block)
end
for(*methods) click to toggle source

Shortcut for Dry::Matcher.for(…, with: matcher)

@param [Array]

@return [Module]

# File lib/dry/matcher.rb, line 99
def for(*methods)
  self.class.for(*methods, with: self)
end