PatternMatching module

Get Version 0.1.2

→ ‘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)”.

Notice: Current implementation is not thread safe now. Need the receiver object(NOT an argument) calling pattern matching synchronized when multi-threaded access.

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

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" 

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 Google Group 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.

Link

Contact

Comments are welcome. Send an email to ICHIYAMA Ryoichi. My blog (written in Japanese) could be help you.

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