PatternMatching module
→ ‘patternmatching’
What
Provides a pure ruby module that:- can build structured objects easily
- can enable pattern match of objects
- can define method as a partial function style
Installing
sudo gem install patternmatching
The basics
This module provides methods for tree pattern matching features.
- For detail, see Wikipedia: Pattern matching
- Syntax based on meta-programming, like “rspec”, and so on.
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