GitHub Sale: sign up for any paid plan this week and pay nothing until January 1, 2009!  [ hide ]

public
Rubygem
Description: Implements pattern-based method dispatch for Ruby, inspired by Topher Cyll's multi.
Clone URL: git://github.com/dyoder/functor.git
Added functor_with_self and corrected bug with class matching.
dyoder (author)
Thu Sep 18 18:44:15 -0700 2008
commit  c7b7c36c47547a10a6a231b3dca681a2769a692d
tree    863ff82b9d34ef4fcd5332a0f9485b6476319c4f
parent  dfd0d7eb1d1b2dc7a040f75d6e3d6379957c9928
...
17
18
19
20
21
 
 
 
 
 
 
 
 
 
22
23
24
...
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
 
51
52
53
...
56
57
58
59
 
60
61
62
...
69
70
71
72
 
73
74
75
...
17
18
19
 
 
20
21
22
23
24
25
26
27
28
29
30
31
...
37
38
39
 
 
 
 
 
 
40
41
42
43
44
45
 
 
 
 
46
 
47
48
49
50
...
53
54
55
 
56
57
58
59
...
66
67
68
 
69
70
71
72
0
@@ -17,8 +17,15 @@ class Functor
0
       end
0
       def k.functor( name, *args, &block )
0
         name = name.to_sym
0
- ( f = ( functors[ name ] or ( functors[ name ] = Functor.new ) ) ).given( *args, &block )
0
- define_method( name ) { | *args | f.apply( self, *args ) }
0
+ ( f = ( functors[ name ] or
0
+ ( functors[ name ] = Functor.new ) ) ).given( *args, &block )
0
+ define_method( name ) { | *args | instance_exec( *args, &f.match( *args ) ) }
0
+ end
0
+ def k.functor_with_self( name, *args, &block )
0
+ name = name.to_sym
0
+ ( f = ( functors[ name ] or
0
+ ( functors[ name ] = Functor.new ) ) ).given( *args, &block )
0
+ define_method( name ) { | *args | instance_exec( *args, &f.match( self, *args ) ) }
0
       end
0
     end
0
   end
0
@@ -30,24 +37,14 @@ class Functor
0
   
0
   def initialize_copy( from )
0
     @rules = from.instance_eval { @rules.clone }
0
- # @rules = from.instance_eval do
0
- # @rules.inject( [] ) do | rules, rule |
0
- # pattern, action = rule
0
- # rules << [ pattern.clone, rule ]
0
- # end
0
- # end
0
   end
0
   
0
   def given( *pattern, &action )
0
     @rules << [ pattern, action ]
0
   end
0
   
0
- def apply( object, *args, &block )
0
- object.instance_exec( *args, &match( args, &block ) )
0
- end
0
-
0
   def call( *args, &block )
0
- match( args, &block ).call( *args )
0
+ match( *args, &block ).call( *args )
0
   end
0
   
0
   def []( *args, &block )
0
@@ -56,7 +53,7 @@ class Functor
0
   
0
   def to_proc ; lambda { |*args| self.call( *args ) } ; end
0
     
0
- def match( args, &block )
0
+ def match( *args, &block )
0
     args << block if block_given?
0
     pattern, action = @rules.reverse.find { | p, a | match?( args, p ) }
0
     action or argument_error( args )
0
@@ -69,7 +66,7 @@ class Functor
0
   end
0
   
0
   def pair?( arg, rule )
0
- ( rule.respond_to? :call and rule.call( arg ) ) or rule === arg or rule == arg
0
+ ( rule.respond_to? :call and rule.call( arg ) ) or rule === arg
0
   end
0
   
0
   def argument_error( args )
...
9
10
11
12
13
14
15
...
22
23
24
25
26
27
28
...
9
10
11
 
12
13
14
...
21
22
23
 
 
 
24
0
@@ -9,7 +9,6 @@ end
0
 
0
 class B < A
0
   functor( :foo, String ) { |s| [ B, String ] }
0
- functor( :foo, Float ) { |f| [ B, *A.functors[:foo].apply( self, f ) ] }
0
 end
0
 
0
 describe "Functor methods should support inheritance" do
0
@@ -22,7 +21,4 @@ describe "Functor methods should support inheritance" do
0
     B.new.foo( "bar" ).should == [ B, String ]
0
   end
0
   
0
- specify "by allowing you to call base class functors using #functors" do
0
- B.new.foo( 1.0 ).should == [ B, A, Float ]
0
- end
0
 end

Comments

    No one has commented yet.