functor 0.3.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,25 @@
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>
7
+ <head>
8
+ <title>included (Functor::Method)</title>
9
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
+ <link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" />
11
+ </head>
12
+ <body class="standalone-code">
13
+ <pre> <span class="ruby-comment cmt"># File lib/functor.rb, line 6</span>
14
+ 6: <span class="ruby-keyword kw">def</span> <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">included</span>( <span class="ruby-identifier">k</span> )
15
+ 7: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">k</span>.<span class="ruby-identifier">functors</span> ; <span class="ruby-ivar">@__functors</span> <span class="ruby-operator">||=</span> {} ; <span class="ruby-keyword kw">end</span>
16
+ 8: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">k</span>.<span class="ruby-identifier">functor</span>( <span class="ruby-identifier">name</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">args</span>, <span class="ruby-operator">&amp;</span><span class="ruby-identifier">block</span> )
17
+ 9: <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">functors</span>[ <span class="ruby-identifier">name</span> ]
18
+ 10: <span class="ruby-identifier">functors</span>[ <span class="ruby-identifier">name</span> ] = <span class="ruby-constant">Functor</span>.<span class="ruby-identifier">new</span>
19
+ 11: <span class="ruby-identifier">klass</span> = <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">name</span> ; <span class="ruby-identifier">module_eval</span> <span class="ruby-value str">&quot;def \#{name}( *args, &amp;block )\nbegin\n\#{klass}.functors[ :\#{name} ].apply( self, *args, &amp;block )\nrescue ArgumentError =&gt; e\nbegin\nsuper\nrescue NoMethodError =&gt; f\nraise e\nend\nend\nend\n&quot;</span>
20
+ 12: <span class="ruby-keyword kw">end</span>
21
+ 13: <span class="ruby-identifier">functors</span>[ <span class="ruby-identifier">name</span> ].<span class="ruby-identifier">given</span>( <span class="ruby-operator">*</span><span class="ruby-identifier">args</span>, <span class="ruby-operator">&amp;</span><span class="ruby-identifier">block</span> )
22
+ 14: <span class="ruby-keyword kw">end</span>
23
+ 15: <span class="ruby-keyword kw">end</span></pre>
24
+ </body>
25
+ </html>
@@ -0,0 +1,147 @@
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: Object</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">Object</td>
54
+ </tr>
55
+ <tr class="top-aligned-row">
56
+ <td><strong>In:</strong></td>
57
+ <td>
58
+ <a href="../files/lib/object_rb.html">
59
+ lib/object.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="#M000007">instance_exec</a>&nbsp;&nbsp;
92
+ </div>
93
+ </div>
94
+
95
+ </div>
96
+
97
+
98
+ <!-- if includes -->
99
+
100
+ <div id="section">
101
+
102
+
103
+
104
+
105
+
106
+
107
+
108
+
109
+ <!-- if method_list -->
110
+ <div id="methods">
111
+ <h3 class="section-bar">Public Instance methods</h3>
112
+
113
+ <div id="method-M000007" class="method-detail">
114
+ <a name="M000007"></a>
115
+
116
+ <div class="method-heading">
117
+ <a href="Object.src/M000007.html" target="Code" class="method-signature"
118
+ onclick="popupCode('Object.src/M000007.html');return false;">
119
+ <span class="method-name">instance_exec</span><span class="method-args">(*args, &amp;block)</span>
120
+ </a>
121
+ </div>
122
+
123
+ <div class="method-description">
124
+ <p>
125
+ This is an extremely powerful little function that will be built-in to Ruby
126
+ 1.9. This version is from Mauricio Fernandez via ruby-talk. Works like
127
+ instance_eval except that you can pass parameters to the block. This means
128
+ you can define a block intended for use with instance_eval, pass it to
129
+ another method, which can then invoke with parameters. This is used quite a
130
+ bit by the Waves::Mapping code.
131
+ </p>
132
+ </div>
133
+ </div>
134
+
135
+
136
+ </div>
137
+
138
+
139
+ </div>
140
+
141
+
142
+ <div id="validator-badges">
143
+ <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
144
+ </div>
145
+
146
+ </body>
147
+ </html>
@@ -0,0 +1,25 @@
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>
7
+ <head>
8
+ <title>instance_exec (Object)</title>
9
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
+ <link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
11
+ </head>
12
+ <body class="standalone-code">
13
+ <pre> <span class="ruby-comment cmt"># File lib/object.rb, line 7</span>
14
+ 7: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">instance_exec</span>(<span class="ruby-operator">*</span><span class="ruby-identifier">args</span>, <span class="ruby-operator">&amp;</span><span class="ruby-identifier">block</span>)
15
+ 8: <span class="ruby-identifier">mname</span> = <span class="ruby-node">&quot;__instance_exec_#{Thread.current.object_id.abs}&quot;</span>
16
+ 9: <span class="ruby-keyword kw">class</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-keyword kw">self</span>; <span class="ruby-keyword kw">self</span> <span class="ruby-keyword kw">end</span>.<span class="ruby-identifier">class_eval</span>{ <span class="ruby-identifier">define_method</span>(<span class="ruby-identifier">mname</span>, <span class="ruby-operator">&amp;</span><span class="ruby-identifier">block</span>) }
17
+ 10: <span class="ruby-keyword kw">begin</span>
18
+ 11: <span class="ruby-identifier">ret</span> = <span class="ruby-identifier">send</span>(<span class="ruby-identifier">mname</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">args</span>)
19
+ 12: <span class="ruby-keyword kw">ensure</span>
20
+ 13: <span class="ruby-keyword kw">class</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-keyword kw">self</span>; <span class="ruby-keyword kw">self</span> <span class="ruby-keyword kw">end</span>.<span class="ruby-identifier">class_eval</span>{ <span class="ruby-identifier">undef_method</span>(<span class="ruby-identifier">mname</span>) } <span class="ruby-keyword kw">rescue</span> <span class="ruby-keyword kw">nil</span>
21
+ 14: <span class="ruby-keyword kw">end</span>
22
+ 15: <span class="ruby-identifier">ret</span>
23
+ 16: <span class="ruby-keyword kw">end</span></pre>
24
+ </body>
25
+ </html>
@@ -0,0 +1 @@
1
+ Mon, 16 Jun 2008 10:19:27 -0700
@@ -0,0 +1,111 @@
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>File: HISTORY</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="fileHeader">
50
+ <h1>HISTORY</h1>
51
+ <table class="header-table">
52
+ <tr class="top-aligned-row">
53
+ <td><strong>Path:</strong></td>
54
+ <td>doc/HISTORY
55
+ </td>
56
+ </tr>
57
+ <tr class="top-aligned-row">
58
+ <td><strong>Last Update:</strong></td>
59
+ <td>Sun Jun 15 18:02:06 -0700 2008</td>
60
+ </tr>
61
+ </table>
62
+ </div>
63
+ <!-- banner header -->
64
+
65
+ <div id="bodyContent">
66
+
67
+
68
+
69
+ <div id="contextContent">
70
+
71
+ <div id="description">
72
+ <p>
73
+ 0.1 - Initial implemention of <a
74
+ href="../../classes/Functor.html">Functor</a> class. 0.2 - Added method
75
+ dispatch, to_proc support, tests. 0.3 - Added support for guards and
76
+ redefinition. 0.3.1 - Made thread-safe and added ability to call base class
77
+ functors.
78
+ </p>
79
+
80
+ </div>
81
+
82
+
83
+ </div>
84
+
85
+
86
+ </div>
87
+
88
+
89
+ <!-- if includes -->
90
+
91
+ <div id="section">
92
+
93
+
94
+
95
+
96
+
97
+
98
+
99
+
100
+ <!-- if method_list -->
101
+
102
+
103
+ </div>
104
+
105
+
106
+ <div id="validator-badges">
107
+ <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
108
+ </div>
109
+
110
+ </body>
111
+ </html>
@@ -0,0 +1,210 @@
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>File: README</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="fileHeader">
50
+ <h1>README</h1>
51
+ <table class="header-table">
52
+ <tr class="top-aligned-row">
53
+ <td><strong>Path:</strong></td>
54
+ <td>doc/README
55
+ </td>
56
+ </tr>
57
+ <tr class="top-aligned-row">
58
+ <td><strong>Last Update:</strong></td>
59
+ <td>Mon Jun 16 10:19:05 -0700 2008</td>
60
+ </tr>
61
+ </table>
62
+ </div>
63
+ <!-- banner header -->
64
+
65
+ <div id="bodyContent">
66
+
67
+
68
+
69
+ <div id="contextContent">
70
+
71
+ <div id="description">
72
+ <p>
73
+ <a href="../../classes/Functor.html">Functor</a> provides pattern-based
74
+ function and method dispatch for Ruby, originally inspired by Topher
75
+ Cyll&#8216;s multi gem.
76
+ </p>
77
+ <h1>Method Functors</h1>
78
+ <p>
79
+ To use it in a class:
80
+ </p>
81
+ <pre>
82
+ class Repeater
83
+ attr_accessor :times
84
+ include Functor::Method
85
+ functor( :repeat, Integer ) { |x| x * @times }
86
+ functor( :repeat, String ) { |s| [].fill( s, 0..@times ).join(' ') }
87
+ end
88
+
89
+ r = Repeater.new
90
+ r.times = 5
91
+ r.repeat( 5 ) # =&gt; 25
92
+ r.repeat( &quot;-&quot; ) # =&gt; &quot;- - - - -&quot;
93
+ r.repeat( 7.3 ) # =&gt; ArgumentError!
94
+ </pre>
95
+ <p>
96
+ Warning: This defines a class instance variable <tt>@__functors</tt> behind
97
+ the scenes as a side-effect. Also, although inheritance works within a
98
+ functor method, super does not. To call the parent method, you need to call
99
+ it explicitly using the <tt>functors</tt> class method, like this:
100
+ </p>
101
+ <pre>
102
+ A.functors[ :foo ].apply( self, 'bar' )
103
+ </pre>
104
+ <h1>Stand-Alone Functors</h1>
105
+ <p>
106
+ You can also define <a href="../../classes/Functor.html">Functor</a>
107
+ objects directly:
108
+ </p>
109
+ <pre>
110
+ fib = Functor.new do
111
+ given( 0 ) { 0 }
112
+ given( 1 ) { 1 }
113
+ given( Integer ) { |n| self.call( n - 1 ) + self.call( n - 2 ) }
114
+ end
115
+ </pre>
116
+ <p>
117
+ You can use functors directly with functions taking a block like this:
118
+ </p>
119
+ <pre>
120
+ [ *0..10 ].map( &amp;fib ) # =&gt; [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
121
+ </pre>
122
+ <p>
123
+ You can call a functor as a method using apply:
124
+ </p>
125
+ <pre>
126
+ fun.apply( obj, 7 )
127
+ </pre>
128
+ <p>
129
+ which is actually how the method functors are implemented.
130
+ </p>
131
+ <h1>Pattern Matching</h1>
132
+ <p>
133
+ Arguments are matched first using === and then ==, so anything that
134
+ supports these methods can be matched against. In addition, you may pass
135
+ &quot;guards,&quot; any object that responds to call and which take and
136
+ object (the argument) and return true or false. This allows you to do
137
+ things like this:
138
+ </p>
139
+ <pre>
140
+ stripe ||= Functor.new do
141
+ given( lambda { |x| x % 2 == 0 } ) { 'white' }
142
+ given( lambda { |x| x % 2 == 1 } ) { 'silver' }
143
+ end
144
+ </pre>
145
+ <p>
146
+ which will return &quot;white&quot; and &quot;silver&quot; alternately for
147
+ a sequence of numbers.
148
+ </p>
149
+ <h1>Precedence</h1>
150
+ <p>
151
+ Precedence is defined in order of declaration: first-come, first-serve, aka
152
+ FIFO. Thus, you need to be careful in how you define your functor. The
153
+ Fibonacci example above would not work properly if the Integer pattern was
154
+ given first. That said, it is possible to redefine earlier cases, which, in
155
+ effect, &quot;demotes&quot; it, as if it had not been declared before. So
156
+ the following will work properly:
157
+ </p>
158
+ <pre>
159
+ fib = Functor.new do
160
+ given( Integer ) { |n| raise &quot;this would start an infinite loop ...&quot; }
161
+ given( 0 ) { 0 }
162
+ given( 1 ) { 1 }
163
+ # but this will &quot;demote&quot; the Integer pattern and now it will work ...
164
+ given( Integer ) { |n| self.call( n - 1 ) + self.call( n - 2 ) }
165
+ end
166
+ </pre>
167
+ <p>
168
+ This isn&#8216;t perfect, but it is very easy to predict, simple to
169
+ implement, and reasonably fast, which other approaches (such as
170
+ implementing a precedence scheme) are not.
171
+ </p>
172
+ <h1>Credits And Support</h1>
173
+ <p>
174
+ <a href="../../classes/Functor.html">Functor</a> was written by Dan Yoder,
175
+ Matthew King, and Lawrence Pit. Send email to dan at zeraweb.com for
176
+ support or questions.
177
+ </p>
178
+
179
+ </div>
180
+
181
+
182
+ </div>
183
+
184
+
185
+ </div>
186
+
187
+
188
+ <!-- if includes -->
189
+
190
+ <div id="section">
191
+
192
+
193
+
194
+
195
+
196
+
197
+
198
+
199
+ <!-- if method_list -->
200
+
201
+
202
+ </div>
203
+
204
+
205
+ <div id="validator-badges">
206
+ <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
207
+ </div>
208
+
209
+ </body>
210
+ </html>