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).(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