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


111
112
113
# File 'lib/fear/pattern_matching_api.rb', line 111

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)


87
88
89
# File 'lib/fear/pattern_matching_api.rb', line 87

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| ... }

If you want to perform pattern destruction, use #xcase method

m.xcase('Date(year, 12, 31)') { |year:| "Last day of the year #{year}" }

The pattern above ensures that it’s 31 of December and extracts year to block named parameter

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:



70
71
72
# File 'lib/fear/pattern_matching_api.rb', line 70

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

#xcase(pattern, *guards) {|hash| ... } ⇒ 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 partial function defined on domain described with guard and perform pattern extraction.

Examples:

pf = Fear.xcase('['ok', Some(body)]') { |body:| ...  }
pf.defined_at?(['ok', Fear.some(body)]) #=> true
pf.defined_at?(['err', Fear.none]) #=> false

pattern and guards. It matches against non-empty body


pf = Fear.xcase('['ok', Some(body)]', ->(body:) { !body.empty? }) { }

Parameters:

  • pattern (String)

    pattern to match against

  • guards (<#===>)

    other guards against extracted pattern

Yield Parameters:

  • hash ({Symbol => any})

Returns:



132
133
134
# File 'lib/fear/pattern_matching_api.rb', line 132

def xcase(pattern, *guards, &function)
  Fear[pattern].and_then(self.case(*guards, &function))
end