Skip to content
 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

51 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

A pattern matching library for Ruby.

$ gem install pattern-match

or

$ git clone git://github.com/k-tsj/pattern-match.git
$ cd pattern-match
$ gem build pattern-match.gemspec
$ gem install pattern-match-*.gem

or

$ gem install bundler (if you need)
$ echo "gem 'pattern-match', :git => 'git://github.com/k-tsj/pattern-match.git'" > Gemfile
$ bundle install --path vendor/bundle
require 'pattern-match'

## (A)
match([0, [1, 2, 3, 4]]) {
  with(_[a, _[b, *c, d]]) { # Same as `Array.(a, Array.(b, *c, d))'
    p [a, b, c, d] #=> [0, 1, [2, 3], 4]
  }
}

## (B)
# From util.match in Gauche: http://practical-scheme.net/gauche/man/?l=en&p=util.match
match([[0, 1], [2, 3]]) {
  with(_[_[a, b], ___]) {
    p [a, b] #=> [[0, 2], [1, 3]]
  }
}

## (C)
# balance in a red-black tree
Node = Struct.new(:left, :key, :right)
class R < Node; end
class B < Node; end

def balance(left, key, right)
  match([left, key, right]) {
    with(_[R.(a, x, b), y, R.(c, z, d)]) { R[B[a, x, b], y, B[c, z, d]] }
    with(_[R.(R.(a, x, b), y, c), z, d]) { R[B[a, x, b], y, B[c, z, d]] }
    with(_[R.(a, x, R.(b, y, c)), z, d]) { R[B[a, x, b], y, B[c, z, d]] }
    with(_[a, x, R.(b, y, R.(c, z, d))]) { R[B[a, x, b], y, B[c, z, d]] }
    with(_[a, x, R.(R.(b, y, c), z, d)]) { R[B[a, x, b], y, B[c, z, d]] }
    with(_) { B[left, key, right] }
  }
end

## (D)
class EMail
  def self.deconstruct(value)
    value.to_s.split(/@/).tap {|parts| raise PatternNotMatch unless parts.length == 2 }
  end
end

match(['foo-bar@example.com', 'baz-bar@example.com']) {
  with(_[mail & EMail.(name & /(\w+)-(\w+)/.(firstname, 'bar'), domain), ___]) {
    p [firstname, name, domain, mail] # => [["foo", "baz"], ["foo-bar", "baz-bar"], ["example.com", "example.com"], ["foo-bar@example.com", "baz-bar@example.com"]]
  }
}

## (E)
match({a: 0, b: 1, c: 2}) {
  with(Hash.(:a, :b, c: 2)) {
    p [a, b] #=> [0, 1]
  }
}

You can see another example in test/test_pattern-match.rb.

$ git clone git://github.com/k-tsj/pattern-match.git
$ cd pattern-match
$ gem install bundler (if you need)
$ bundle install --path vendor/bundle
$ rake test (or simply type "rake")
$ rake build

About

A pattern matching library for Ruby

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages