matchrb (pronounced 'matcherby') provides a simple but powerful way to do pattern matching in Ruby.
Add this line to your application's Gemfile:
gem 'matchrb'
And then execute:
$ bundle
Or install it yourself as:
$ gem install matchrb
matchrb implements two methods, #match
and #otherwise
. You can use them
globaly like so:
require 'matchrb/global'
object = 100
match object,
String => "object is a string",
Integer => "object is an integer",
otherwise => "object is...just an object"
# => "object is an integer"
or, to avoid name clashes, use them individually:
require 'matchrb'
object = 100
Matchrb.match object,
String => "object is a string",
Integer => "object is an integer",
Matchrb.otherwise => "object is...just an object"
# => "object is an integer"
It also has some functionality akin to extractors in Scala. All you have to do
is return some object from #===
.
Multiple = Class.new do
def self.of(number)
new(number)
end
def initialize(number)
@number = number
end
def ===(object)
object % @number == 0 ? object/@number : false
end
end
match 99,
Multiple.of(3) => ->(value) { value }
#=> 33
It's not as powerful, though: you can't return a falsy value. The implementation is too simple as of yet.
If you're one of those that like Fizz Buzz programs:
divisible_by = lambda {|number, value| value % number == 0}.curry
(1..100).each do |i|
puts match i,
divisible_by[15] => "Fizz Buzz",
divisible_by[5] => "Buzz",
divisible_by[3] => "Fizz",
otherwise => i
end
-
Proper objects for matching, instead of relying on truthy/falsy values (perhaps Some/None). With this you can return
nil
orfalse
from the matcher and have it used by thelambda
/proc
on the right hand side. -
Yielding of matched value to any callable, not just extractors. With this you can do things like:
class Multiplier def initialize(by) @by = by end def to_proc method(:call) end def call(value) value * @by end end match 10, Integer => Multiplier.new(10) #=> 100
-
Lots of other proper matching idioms.
- Fork it ( https://github.com/dlisboa/matchrb/fork )
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request
(The BSD License)
Copyright (c) 2014 Diogo Lisboa
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
-
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
-
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.