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)
”.
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 APIrequire "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"
Pattern with Condition Example
It is from ver 0.2.2 APIrequire "patternmatching" include PatternMatching num = 100 result = make num do seems as {:n}, with {n < 10} do true end seems as {:n}, with {n >= 10} do false end end p result #=> false
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
- ICHIYAMA Ryoichi: bellbind at gmail dot com
My blog (written in Japanese) could be help you.
Dr Nic, 6th June 2007
Theme extended from Paul Battley