pattern matching Proc definitions
pattern-proc is a Ruby gem designed to allow creation of pattern-matching procs in a repeated declaration mechanism similar to Haskell.
Usage:
require 'pattern-proc'
-
manually instantiate a proc
cool_proc = PatternProc.new cool_proc.with(5,10).returns(30) cool_proc.with(3,70).returns(111) cool_proc.with(3) do |second_arg| second_arg * 10 end cool_proc.with do |first_arg, second_arg| do first_arg * second_arg end # later... regular_proc = cool_proc.to_proc regular_proc.(5,10) \> 30 regular_proc.(3).(70) \> 111 regular_proc.(3).(15) \> 150 # second_arg * 10 case regular_proc.(5,5) \> 25 # first_arg * second_arg case
-
declare methods in a class
class MyClass include PatternProc::ClassMethods pattern(:my_func).with(3,10).returns(30) pattern(:my_func).with(4,11).returns(40) end # later... obj = MyClass.new obj.my_func(3,10) \> 30 obj.my_func(4).(11) \> 40 # or class MySingletonClass class << self include PatternProc::ClassMethods pattern(:my_class_func).with(:a, :b).returns(:c) pattern(:my_class_func).with(:c) do |other| other.to_s end end end
-
"mock" out Funkify-style partial application methods in tests
include PatternProc::TestMethods describe 'something' do it '"mocks" methods' do mock_obj = mock 'anything' mock_obj.pattern(:my_func).with(1,2).returns(10) mock_obj.pattern(:my_func).with(1) do |x| x + 3 end mock_obj.my_func(1).(2).should == 10 mock_obj.my_func(1,5).should == 8 SomeClass.pattern(:existing_func).with("hello").returns("goodbye") SomeClass.exsting_func("hello").should == "goodbyes" end end
This gem was initially created to ease testing when using the Funkify gem, as is most clear in the last example. However I would like to build on this library and make the ClassMethods "DSL" more robust. Additionally, right now pattern matching is done by specificity rather than declaration order, and you can only define a proc implementation for the rightmost N arguments (as opposed to any set of arguments, eg.
do_stuff 5 x = x * 2
in Haskell). Finally I would like PatternProc to subclass Proc directly rather than requiring a call to to_proc.