PatternMatching module

Get Version 0.2.0

→ ‘patternmatching’

What

Provides a pure ruby module that:

Installing

sudo gem install patternmatching

The basics

This module provides methods for tree pattern matching features.

Note: Default equivalence used in structured pattern matching is based on “pattern === data”, so “foo(Numeric)” matches “foo(100)”.

From ver. 0.2.0, thread unsafeness restriction is removed.

Demonstration of usage

Symbols(e.g. :a, :right_value) in patterns is passed as variable to the following block when the pattern matched.

Pattern matching expression

# If installed from gem
# require "rubygems" 
# gem "patternmatching" 
require "patternmatching" 

# For DSL style code, include PatternMatching
include PatternMatching

# match example
def calc(code)
  make(code) {
    seems as {plus(:a, :b)} do calc(a) + calc(b) end
    seems as {mul(:a, :b)} do  calc(a) * calc(b) end
    seems something do code end
  }
end

code = build {plus(mul(100, 100), 200)}
p calc(code) #=> 10200

Partial style method

require "patternmatching" 

# Structured data builder
code = PatternMatching.build {plus(mul(100, 100), 200)}

# Partial style method example
class Calc
  # At first, extends with the module
  extend PatternMatching

  # def calcm(o), as 3 partial styles
  func(:calcm).seems as {plus(:a, :a)} do
    calcm(b) + calcm(b)
  end
  func(:calcm).seems as {mul(:a, :b)} do
    calcm(a) * calcm(b)
  end
  func(:calcm).seems as {:value} do
    value
  end
end

# use as standard method
p Calc.new.calcm(code) #=> 10200

Array/Enumerable pattern

require "patternmatching" 

include PatternMatching

# Example for matching Enumerable
is = build { exact([1,2,3,4,5]) }
make is do
   # _!  matches rest of lists
  seems as {exact([:a,:b, _!(:c)])} do
    puts a.to_s + ", " + b.to_s  + " and " + c.to_s
  end
  seems something do
    puts "not matched" 
  end
end # => "1, 2, and 345" 

Hash pattern

require "patternmatching" 

include PatternMatching

# Example for matching Hash
dict = build { {:name => "Taro", :age => 5} }
make dict do
  seems as {{:name => :name}} do
    puts "He is " + name
  end
  seems something do
    puts "no name" 
  end
end # => "He is Taro" 

Non-Hash/Object pattern

require "patternmatching" 

include PatternMatching

class Person
  def initialize(name, age)
    @name = name
    @age = age
  end
  attr :name
  attr :age
end

# Example for matching Object except Hash
person = Person.new("Jiro", 3)
make person do
  seems as {{:name => :name}} do
    puts "He is " + name
  end
  seems something do
    puts "no name" 
  end
end # => "He is Jiro" 

Field Access Example

It is ver 0.2.0 API
require "patternmatching" 

include PatternMatching

class Foo 
  def initialize
    @name = "Foo" 
  end
  attr :name
  def foo
  end

  def bar
    make "bar" do
      seems as {:val} do
        foo
        # To access fields like this.name or this.name = ...
        the.name = val
        # To access self as this
        this
      end
    end
  end

  func(:buzz).seems as {:val} do 
    the.name = val
    this
  end
end

o = Foo.new
p o.bar == o #=> true 
p o.name #=> "bar" 
p o.buzz("buzz") == o #=> true
p o.name #=> "buzz" 

Forum

Visit RubyForge project forum.

How to submit patches

Read the 8 steps for fixing other people’s code and for section 8b: Submit patch to Google Groups, use the forum above.

The trunk repository is svn://rubyforge.org/var/svn/patternmatching/trunk for anonymous access.

License

This code is free to use under the terms of the MIT license.

Links

Contact

Comments are welcome. Send a message to the forum.

Authors

My blog (written in Japanese) could be help you.

Dr Nic, 5th June 2007
Theme extended from Paul Battley