require File.dirname(__FILE__) + '/spec_helper.rb' require 'patternmatching' class CalcM # At first, extends with the module extend PatternMatching # def calcm(o), as 3 partial styles func(:calcm).seems as {plus(:left, :right)} do calcm(left) + calcm(right) end func(:calcm).seems as {mul(:left, :right)} do calcm(left) * calcm(right) end func(:calcm).seems as {:value} do value end end class CalcX extend PatternMatching func(:calcx) do seems as {plus(:left, :right)} do calcx(left) + calcx(right) end seems as {mul(:left, :right)} do calcx(left) * calcx(right) end end func(:calcx).seems as {:value} do value end end class Person def initialize(name, age) @name = name @age = age end attr :name attr :age end include PatternMatching class PartialStyleDefs def initialize @name = "Foo" end attr :name def foo self end def bar make "bar" do seems as {:val} do foo the.name = val this end end end func(:buzz).seems as {:val} do foo the.name = val this end end 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 describe "PatternMatching from Example" do it "shuold run calcm as a regular method." do code = PatternMatching.build {plus(mul(100, 100), 200)} ret = CalcM.new.calcm(code) ret.should == 10200 end it "shuold run calcx as a regular method." do code = PatternMatching.build {plus(mul(100, 100), 200)} ret = CalcX.new.calcx(code) ret.should == 10200 end it "should run calc as a regular function." do code = PatternMatching.build {plus(mul(100, 100), 200)} ret = calc(code) ret.should == 10200 end it "should look Enumerable pattern." do is = build { exact([1,2,3,4,5]) } result = make is do seems as {exact([:a,:b,:c])} do # not match a.to_s + " and " + b.to_s + " and" + c.to_s end seems as {exact([:a,:b, _!(:c)])} do a.to_s + ", " + b.to_s + " and " + c.join(", ") end seems something do "not matched" end end result.should == "1, 2 and 3, 4, 5" end it "should look Just Enumerable pattern." do is = build { exact([1,2,3,4,5]) } result = make is do seems as {exact([:a,:b,:c])} do # not match a.to_s + " and " + b.to_s + " and" + c.to_s end seems as {exact([:a,:b, :c, :d, :e])} do a.to_s + ", " + b.to_s + ", " + c.to_s + ", " + d.to_s + ", " + e.to_s end seems something do "not matched" end end result.should == "1, 2, 3, 4, 5" end it "should look Hash pattern." do dict = build { {:name => "Taro", :age => 5} } result = make dict do seems as {{:name => :name}} do "He is " + name end seems something do "no name" end end result.should == "He is Taro" end it "should look non-Hash pattern." do person = Person.new("Jiro", 3) result = make person do seems as {{:name => :name}} do "He is " + name end seems something do "no name" end end result.should == "He is Jiro" end it "should look nested pattern." do code = build {plus(mul(100, 120, 300), plus(200, 150))} result = make code do seems as {plus(plus(:a, :b, _), plus(:c, _))} do # not match [a, b, c] end seems as {plus(mul(_, :a, _), plus(:b, _))} do [a, b] end seems something do nil end end result.should == [120, 200] end it "should look wildcard node pattern." do code = build {plus(mul(100, 120, 300), plus(200, 150))} result = make code do seems as {_(_(_, _, :a), mul(_, :b))} do # not match [a, b] end seems as {plus(_(_, :a, _), _(:b, _))} do [a, b] end seems something do nil end end result.should == [120, 200] end it "should update fields from block" do o = PartialStyleDefs.new o.name.should == "Foo" o.bar.should == o o.name.should == "bar" o.buzz("buzz").should == o o.name.should == "buzz" end it "should check pattern with condition" do make(100) do seems as {:a}, with {a > 10} do a end end.should == 100 make(1) do seems as {:a}, with {a > 10} do a end end.should == nil end end