Module: Fear::PatternMatchingApi Private

Included in:
Fear
Defined in:
lib/fear/pattern_matching_api.rb

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

Instance Method Summary collapse

Instance Method Details

#case(*guards, &function) ⇒ Fear::PartialFunction

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.

Note:

to make more complex matches, you are encouraged to use Qo gem.

Creates partial function defined on domain described with guards

Examples:

pf = Fear.case(Integer) { |x| x / 2 }
pf.defined_at?(4) #=> true
pf.defined_at?('Foo') #=> false

multiple guards combined using logical “and”

pf = Fear.case(Integer, :even?.to_proc) { |x| x / 2 }
pf.defined_at?(4) #=> true
pf.defined_at?(3) #=> false
Fear.case(Qo[age: 20..30]) { |_| 'old enough' }

Parameters:

  • guards (<#===>)
  • function (Proc)

Returns:

See Also:

  • https://github.com/baweaver/qo


105
106
107
# File 'lib/fear/pattern_matching_api.rb', line 105

def case(*guards, &function)
  PartialFunction.and(*guards, &function)
end

#match(value) {|matcher| ... } ⇒ any

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.

Pattern match against given value

Examples:

Fear.match(42) do |m|
  m.case(Integer, :even?.to_proc) { |n| "#{n} is even number" }
  m.case(Integer, :odd?.to_proc) { |n| "#{n} is odd number" }
  m.case(Strings) { |n| "#{n} is a string" }
  m.else { 'unknown' }
end #=> "42 is even number"

Parameters:

  • value (any)

Yield Parameters:

Returns:

  • (any)


81
82
83
# File 'lib/fear/pattern_matching_api.rb', line 81

def match(value, &block)
  matcher(&block).call(value)
end

#matcher {|matcher| ... } ⇒ Fear::PartialFunction

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.

Creates pattern match. Use case method to define matching branches. Branch consist of a guardian, which describes domain of the branch and function to apply to matching value.

if you pass something other than Integer or string, it will raise Fear::MatchError:

matcher.(10..20) #=> raises Fear::MatchError

to avoid raising MatchError, you can use else method. It defines a branch matching on any value.

matcher = Fear.matcher do |m|
  m.case(Integer) { |n| "#{n} is a number" }
  m.case(String) { |n| "#{n} is a string" }
  m.else  { |n| "#{n} is a #{n.class}" }
end

matcher.(10..20) #=> "10..20 is a Range"

You can use anything as a guardian if it responds to ‘#===` method:

m.case(20..40) { |m| "#{m} is within range" }
m.case(->(x) { x > 10}) { |m| "#{m} is greater than 10" }
m.case(:even?.to_proc) { |x| "#{x} is even" }
m.case(:odd?.to_proc) { |x| "#{x} is odd" }

It’s also possible to pass several guardians. All should match to pass

m.case(Integer, :even?.to_proc) { |x| ... }
m.case(Integer, :odd?.to_proc) { |x| ... }

Since matcher returns Fear::PartialFunction, you can combine matchers using partial function API:

failures = Fear.matcher do |m|
  m.case('not_found') { ... }
  m.case('network_error') { ... }
end

success = Fear.matcher do |m|
  m.case('ok') { ... }
end

response = failures.or_else(success)

Examples:

This mather apply different functions to Integers and to Strings

matcher = Fear.matcher do |m|
  m.case(Integer) { |n| "#{n} is a number" }
  m.case(String) { |n| "#{n} is a string" }
end

matcher.(42) #=> "42 is a number"
matcher.("Foo") #=> "Foo is a string"

Yield Parameters:

Returns:

See Also:

  • for example of custom matcher


64
65
66
# File 'lib/fear/pattern_matching_api.rb', line 64

def matcher(&block)
  PatternMatch.new(&block)
end