Class: Qo::Matchers::PatternMatchBlock
- Inherits:
-
Object
- Object
- Qo::Matchers::PatternMatchBlock
- Defined in:
- lib/qo/matchers/pattern_match_block.rb
Overview
Creates a PatternMatch in the style of a block.
This varies from the regular PatternMatch in that all matchers are provided in a more succinct block format:
Qo.match(target) { |m|
m.when(/^F/, 42) { |(name, age)| "#{name} is #{age}" }
m.else { "We need a default, right?" }
}
The Public API obscures the fact that the matcher is only called when it is explicitly given an argument to match against. If it is not, it will just return a class waiting for a target, as such:
def get_url(url)
Net::HTTP.get_response(URI(url)).yield_self(&Qo.match { |m|
m.when(Net::HTTPSuccess) { |response| response.body.size }
m.else { |response| raise response. }
})
end
get_url('https://github.com/baweaver/qo')
# => 142387
get_url('https://github.com/baweaver/qo/does_not_exist')
# => RuntimeError: Not Found
This is intended for flexibility between singular calls and calls as a
paramater to higher order functions like map
and yield_self
.
This variant was inspired by ideas from Scala, Haskell, and various Ruby libraries dealing with Async and self-yielding blocks. Especially notable were websocket handlers and dry-ruby implementations.
Instance Method Summary collapse
-
#call(target) ⇒ Any | nil
Immediately invokes a PatternMatch.
-
#else(&fn) ⇒ Proc
Else is the last statement that will be evaluated if all other parts fail.
-
#initialize {|_self| ... } ⇒ PatternMatchBlock
constructor
A new instance of PatternMatchBlock.
-
#to_proc ⇒ Proc
Proc version of a PatternMatchBlock.
-
#when(*array_matchers, **keyword_matchers, &fn) ⇒ Array[GuardBlockMatcher]
Creates a match case.
Constructor Details
#initialize {|_self| ... } ⇒ PatternMatchBlock
Returns a new instance of PatternMatchBlock
46 47 48 49 50 |
# File 'lib/qo/matchers/pattern_match_block.rb', line 46 def initialize @matchers = [] yield(self) end |
Instance Method Details
#call(target) ⇒ Any | nil
Immediately invokes a PatternMatch
103 104 105 106 107 108 109 110 111 112 |
# File 'lib/qo/matchers/pattern_match_block.rb', line 103 def call(target) @matchers.each { |guard_block_matcher| did_match, match_result = guard_block_matcher.call(target) return match_result if did_match } return @else.call(target) if @else nil end |
#else(&fn) ⇒ Proc
Else is the last statement that will be evaluated if all other parts
fail. It should be noted that it won't magically appear, you have to
explicitly put an else
case in for it to catch on no match unless
you want a nil
return
83 84 85 86 |
# File 'lib/qo/matchers/pattern_match_block.rb', line 83 def else(&fn) raise Qo::Exceptions::MultipleElseClauses if @else @else = fn end |
#to_proc ⇒ Proc
Proc version of a PatternMatchBlock
92 93 94 |
# File 'lib/qo/matchers/pattern_match_block.rb', line 92 def to_proc Proc.new { |target| self.call(target) } end |
#when(*array_matchers, **keyword_matchers, &fn) ⇒ Array[GuardBlockMatcher]
Creates a match case. This is the exact same as any other and
style
match reflected in the public API, except that it's a Guard Block
match being performed. That means if the left side matches, the right
side function is invoked and that value is returned.
70 71 72 |
# File 'lib/qo/matchers/pattern_match_block.rb', line 70 def when(*array_matchers, **keyword_matchers, &fn) @matchers << Qo::Matchers::GuardBlockMatcher.new(*array_matchers, **keyword_matchers, &fn) end |