functor 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/test/reopening.rb CHANGED
@@ -1,18 +1,18 @@
1
1
  require "#{File.dirname(__FILE__)}/helpers"
2
2
 
3
- class A
3
+ class Reopening
4
4
  include Functor::Method
5
5
  functor( :foo, Integer ) { |x| 1 }
6
6
  end
7
7
 
8
- class A
8
+ class Reopening
9
9
  functor( :foo, Integer ) { |x| 2 }
10
10
  end
11
11
 
12
12
  describe "Functor methods should support reopening" do
13
13
 
14
14
  specify "by allowing reopening of a class to override an implementation" do
15
- A.new.foo( 5 ).should == 2
15
+ Reopening.new.foo( 5 ).should == 2
16
16
  end
17
17
 
18
18
  end
@@ -0,0 +1,20 @@
1
+ require "#{File.dirname(__FILE__)}/helpers"
2
+
3
+ class Additive
4
+ include Functor::Method
5
+
6
+ def foo(*args)
7
+ args.reverse
8
+ end
9
+
10
+ functor( :foo, Integer ) { |x| 1 }
11
+ end
12
+
13
+ describe "A Functor method" do
14
+
15
+ specify "supplements, rather than obliterating, an existing method" do
16
+ Additive.new.foo( 5 ).should == 1
17
+ Additive.new.foo( :a, :b).should == [ :b, :a ]
18
+ end
19
+
20
+ end
data/test/wildcard.rb ADDED
@@ -0,0 +1,15 @@
1
+ require "#{File.dirname(__FILE__)}/helpers"
2
+
3
+ class Wildcard
4
+ include Functor::Method
5
+ functor( :foo, Integer, _whatever ) { |int, whatever| "#{int}: #{whatever}" }
6
+ end
7
+
8
+ describe "A functor" do
9
+
10
+ it "can use a method beginning with '_' to match anything" do
11
+ c = Wildcard.new
12
+ c.foo( 7, "Smurf").should == "7: Smurf"
13
+ end
14
+
15
+ end
data/test/with_self.rb CHANGED
@@ -1,21 +1,26 @@
1
1
  require "#{File.dirname(__FILE__)}/helpers"
2
2
 
3
- class A
3
+ class WithSelf
4
4
  attr_accessor :bar
5
5
  include Functor::Method
6
6
  def initialize( x ) ; @bar = x ; end
7
7
  functor_with_self( :foo, self, Integer ) { |x| x }
8
8
  functor_with_self( :foo, lambda{ |x| x.bar == true }, Integer ) { |s| 'bar' }
9
+ functor_with_self( :foo, lambda{ |x| x.bar.is_a? String }, Integer ) { |s| 'I be string' }
9
10
  end
10
11
 
11
12
  describe "Functor methods should support allow matching on self" do
12
13
 
13
14
  specify "by allowing functor_with_self to provide a guard on self" do
14
- A.new( true ).foo( 5 ).should == 'bar'
15
+ WithSelf.new( true ).foo( 5 ).should == 'bar'
15
16
  end
16
17
 
17
18
  specify "or by simply providing self as an argument" do
18
- A.new( false ).foo( 5 ).should == 5
19
+ WithSelf.new( false ).foo( 5 ).should == 5
20
+ end
21
+
22
+ specify "another guard example, for those who need it" do
23
+ WithSelf.new( "me" ).foo( 87 ).should == "I be string"
19
24
  end
20
25
 
21
26
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: functor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Yoder
@@ -11,7 +11,7 @@ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
13
 
14
- date: 2008-10-08 00:00:00 -07:00
14
+ date: 2009-11-21 00:00:00 -08:00
15
15
  default_executable:
16
16
  dependencies: []
17
17
 
@@ -25,38 +25,11 @@ extra_rdoc_files: []
25
25
 
26
26
  files:
27
27
  - doc/HISTORY
28
- - doc/rdoc
29
- - doc/rdoc/classes
30
- - doc/rdoc/classes/Functor
31
- - doc/rdoc/classes/Functor/Method.html
32
- - doc/rdoc/classes/Functor/Method.src
33
- - doc/rdoc/classes/Functor/Method.src/M000006.html
34
- - doc/rdoc/classes/Functor.html
35
- - doc/rdoc/classes/Functor.src
36
- - doc/rdoc/classes/Functor.src/M000001.html
37
- - doc/rdoc/classes/Functor.src/M000002.html
38
- - doc/rdoc/classes/Functor.src/M000003.html
39
- - doc/rdoc/classes/Functor.src/M000004.html
40
- - doc/rdoc/classes/Functor.src/M000005.html
41
- - doc/rdoc/classes/Object.html
42
- - doc/rdoc/classes/Object.src
43
- - doc/rdoc/classes/Object.src/M000007.html
44
- - doc/rdoc/created.rid
45
- - doc/rdoc/files
46
- - doc/rdoc/files/doc
47
- - doc/rdoc/files/doc/HISTORY.html
48
- - doc/rdoc/files/doc/README.html
49
- - doc/rdoc/files/lib
50
- - doc/rdoc/files/lib/functor_rb.html
51
- - doc/rdoc/files/lib/object_rb.html
52
- - doc/rdoc/fr_class_index.html
53
- - doc/rdoc/fr_file_index.html
54
- - doc/rdoc/fr_method_index.html
55
- - doc/rdoc/index.html
56
- - doc/rdoc/rdoc-style.css
57
- - doc/README
58
28
  - lib/functor.rb
59
- - lib/object.rb
29
+ - metrics/benchmark.rb
30
+ - metrics/helpers.rb
31
+ - metrics/many_args.rb
32
+ - metrics/one_arg.rb
60
33
  - test/fib.rb
61
34
  - test/functor.rb
62
35
  - test/guards.rb
@@ -64,9 +37,13 @@ files:
64
37
  - test/inheritance.rb
65
38
  - test/matchers.rb
66
39
  - test/reopening.rb
40
+ - test/supplement.rb
41
+ - test/wildcard.rb
67
42
  - test/with_self.rb
68
43
  has_rdoc: true
69
44
  homepage: http://dev.zeraweb.com/
45
+ licenses: []
46
+
70
47
  post_install_message:
71
48
  rdoc_options: []
72
49
 
@@ -87,9 +64,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
87
64
  requirements: []
88
65
 
89
66
  rubyforge_project: functor
90
- rubygems_version: 1.2.0
67
+ rubygems_version: 1.3.5
91
68
  signing_key:
92
- specification_version: 2
69
+ specification_version: 3
93
70
  summary: Pattern-based dispatch for Ruby, inspired by Topher Cyll's multi.
94
71
  test_files: []
95
72
 
data/doc/README DELETED
@@ -1,71 +0,0 @@
1
- Functor provides pattern-based function and method dispatch for Ruby, originally inspired by Topher Cyll's multi gem.
2
-
3
- = Method Functors
4
-
5
- To use it in a class:
6
-
7
- class Repeater
8
- attr_accessor :times
9
- include Functor::Method
10
- functor( :repeat, Integer ) { |x| x * @times }
11
- functor( :repeat, String ) { |s| [].fill( s, 0..@times ).join(' ') }
12
- end
13
-
14
- r = Repeater.new
15
- r.times = 5
16
- r.repeat( 5 ) # => 25
17
- r.repeat( "-" ) # => "- - - - -"
18
- r.repeat( 7.3 ) # => ArgumentError!
19
-
20
- Warning: This defines a class instance variable <tt>@__functors</tt> behind the scenes as a side-effect. Also, although inheritance works within a functor method, super does not. To call the parent method, you need to call it explicitly using the <tt>#functors</tt> class method, like this:
21
-
22
- A.functors[ :foo ].apply( self, 'bar' )
23
-
24
- = Stand-Alone Functors
25
-
26
- You can also define Functor objects directly:
27
-
28
- fib = Functor.new do
29
- given( 0 ) { 0 }
30
- given( 1 ) { 1 }
31
- given( Integer ) { |n| self.call( n - 1 ) + self.call( n - 2 ) }
32
- end
33
-
34
- You can use functors directly with functions taking a block like this:
35
-
36
- [ *0..10 ].map( &fib ) # => [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
37
-
38
- You can call a functor as a method using #apply:
39
-
40
- fun.apply( obj, 7 )
41
-
42
- which is actually how the method functors are implemented.
43
-
44
- = Pattern Matching
45
-
46
- Arguments are matched first using === and then ==, so anything that supports these methods can be matched against. In addition, you may pass "guards," any object that responds to #call and which take and object (the argument) and return true or false. This allows you to do things like this:
47
-
48
- stripe ||= Functor.new do
49
- given( lambda { |x| x % 2 == 0 } ) { 'white' }
50
- given( lambda { |x| x % 2 == 1 } ) { 'silver' }
51
- end
52
-
53
- which will return "white" and "silver" alternately for a sequence of numbers.
54
-
55
- = Precedence
56
-
57
- Precedence is defined in order of declaration: first-come, first-serve, aka FIFO. Thus, you need to be careful in how you define your functor. The Fibonacci example above would not work properly if the Integer pattern was given first. That said, it is possible to redefine earlier cases, which, in effect, "demotes" it, as if it had not been declared before. So the following will work properly:
58
-
59
- fib = Functor.new do
60
- given( Integer ) { |n| raise "this would start an infinite loop ..." }
61
- given( 0 ) { 0 }
62
- given( 1 ) { 1 }
63
- # but this will "demote" the Integer pattern and now it will work ...
64
- given( Integer ) { |n| self.call( n - 1 ) + self.call( n - 2 ) }
65
- end
66
-
67
- This isn't perfect, but it is very easy to predict, simple to implement, and reasonably fast, which other approaches (such as implementing a precedence scheme) are not.
68
-
69
- = Credits And Support
70
-
71
- Functor was written by Dan Yoder, Matthew King, and Lawrence Pit. Send email to dan at zeraweb.com for support or questions.
@@ -1,207 +0,0 @@
1
- <?xml version="1.0" encoding="iso-8859-1"?>
2
- <!DOCTYPE html
3
- PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
-
6
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7
- <head>
8
- <title>Class: Functor</title>
9
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
- <meta http-equiv="Content-Script-Type" content="text/javascript" />
11
- <link rel="stylesheet" href=".././rdoc-style.css" type="text/css" media="screen" />
12
- <script type="text/javascript">
13
- // <![CDATA[
14
-
15
- function popupCode( url ) {
16
- window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17
- }
18
-
19
- function toggleCode( id ) {
20
- if ( document.getElementById )
21
- elem = document.getElementById( id );
22
- else if ( document.all )
23
- elem = eval( "document.all." + id );
24
- else
25
- return false;
26
-
27
- elemStyle = elem.style;
28
-
29
- if ( elemStyle.display != "block" ) {
30
- elemStyle.display = "block"
31
- } else {
32
- elemStyle.display = "none"
33
- }
34
-
35
- return true;
36
- }
37
-
38
- // Make codeblocks hidden by default
39
- document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
-
41
- // ]]>
42
- </script>
43
-
44
- </head>
45
- <body>
46
-
47
-
48
-
49
- <div id="classHeader">
50
- <table class="header-table">
51
- <tr class="top-aligned-row">
52
- <td><strong>Class</strong></td>
53
- <td class="class-name-in-header">Functor</td>
54
- </tr>
55
- <tr class="top-aligned-row">
56
- <td><strong>In:</strong></td>
57
- <td>
58
- <a href="../files/lib/functor_rb.html">
59
- lib/functor.rb
60
- </a>
61
- <br />
62
- </td>
63
- </tr>
64
-
65
- <tr class="top-aligned-row">
66
- <td><strong>Parent:</strong></td>
67
- <td>
68
- <a href="Object.html">
69
- Object
70
- </a>
71
- </td>
72
- </tr>
73
- </table>
74
- </div>
75
- <!-- banner header -->
76
-
77
- <div id="bodyContent">
78
-
79
-
80
-
81
- <div id="contextContent">
82
-
83
-
84
-
85
- </div>
86
-
87
- <div id="method-list">
88
- <h3 class="section-bar">Methods</h3>
89
-
90
- <div class="name-list">
91
- <a href="#M000003">apply</a>&nbsp;&nbsp;
92
- <a href="#M000004">call</a>&nbsp;&nbsp;
93
- <a href="#M000002">given</a>&nbsp;&nbsp;
94
- <a href="#M000001">new</a>&nbsp;&nbsp;
95
- <a href="#M000005">to_proc</a>&nbsp;&nbsp;
96
- </div>
97
- </div>
98
-
99
- </div>
100
-
101
-
102
- <!-- if includes -->
103
-
104
- <div id="section">
105
-
106
- <div id="class-list">
107
- <h3 class="section-bar">Classes and Modules</h3>
108
-
109
- Module <a href="Functor/Method.html" class="link">Functor::Method</a><br />
110
-
111
- </div>
112
-
113
-
114
-
115
-
116
-
117
-
118
-
119
- <!-- if method_list -->
120
- <div id="methods">
121
- <h3 class="section-bar">Public Class methods</h3>
122
-
123
- <div id="method-M000001" class="method-detail">
124
- <a name="M000001"></a>
125
-
126
- <div class="method-heading">
127
- <a href="Functor.src/M000001.html" target="Code" class="method-signature"
128
- onclick="popupCode('Functor.src/M000001.html');return false;">
129
- <span class="method-name">new</span><span class="method-args">( &amp;block )</span>
130
- </a>
131
- </div>
132
-
133
- <div class="method-description">
134
- </div>
135
- </div>
136
-
137
- <h3 class="section-bar">Public Instance methods</h3>
138
-
139
- <div id="method-M000003" class="method-detail">
140
- <a name="M000003"></a>
141
-
142
- <div class="method-heading">
143
- <a href="Functor.src/M000003.html" target="Code" class="method-signature"
144
- onclick="popupCode('Functor.src/M000003.html');return false;">
145
- <span class="method-name">apply</span><span class="method-args">( object, *args, &amp;block )</span>
146
- </a>
147
- </div>
148
-
149
- <div class="method-description">
150
- </div>
151
- </div>
152
-
153
- <div id="method-M000004" class="method-detail">
154
- <a name="M000004"></a>
155
-
156
- <div class="method-heading">
157
- <a href="Functor.src/M000004.html" target="Code" class="method-signature"
158
- onclick="popupCode('Functor.src/M000004.html');return false;">
159
- <span class="method-name">call</span><span class="method-args">( *args, &amp;block )</span>
160
- </a>
161
- </div>
162
-
163
- <div class="method-description">
164
- </div>
165
- </div>
166
-
167
- <div id="method-M000002" class="method-detail">
168
- <a name="M000002"></a>
169
-
170
- <div class="method-heading">
171
- <a href="Functor.src/M000002.html" target="Code" class="method-signature"
172
- onclick="popupCode('Functor.src/M000002.html');return false;">
173
- <span class="method-name">given</span><span class="method-args">( *pattern, &amp;action )</span>
174
- </a>
175
- </div>
176
-
177
- <div class="method-description">
178
- </div>
179
- </div>
180
-
181
- <div id="method-M000005" class="method-detail">
182
- <a name="M000005"></a>
183
-
184
- <div class="method-heading">
185
- <a href="Functor.src/M000005.html" target="Code" class="method-signature"
186
- onclick="popupCode('Functor.src/M000005.html');return false;">
187
- <span class="method-name">to_proc</span><span class="method-args">()</span>
188
- </a>
189
- </div>
190
-
191
- <div class="method-description">
192
- </div>
193
- </div>
194
-
195
-
196
- </div>
197
-
198
-
199
- </div>
200
-
201
-
202
- <div id="validator-badges">
203
- <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
204
- </div>
205
-
206
- </body>
207
- </html>