functor 0.3.1 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/doc/HISTORY +2 -1
- data/doc/README +34 -8
- data/doc/rdoc/classes/Functor.html +207 -0
- data/doc/rdoc/classes/Functor.src/M000001.html +18 -0
- data/doc/rdoc/classes/Functor.src/M000002.html +19 -0
- data/doc/rdoc/classes/Functor.src/M000003.html +18 -0
- data/doc/rdoc/classes/Functor.src/M000004.html +19 -0
- data/doc/rdoc/classes/Functor.src/M000005.html +16 -0
- data/doc/rdoc/classes/Functor/Method.html +131 -0
- data/doc/rdoc/classes/Functor/Method.src/M000006.html +25 -0
- data/doc/rdoc/classes/Object.html +147 -0
- data/doc/rdoc/classes/Object.src/M000007.html +25 -0
- data/doc/rdoc/created.rid +1 -0
- data/doc/rdoc/files/doc/HISTORY.html +111 -0
- data/doc/rdoc/files/doc/README.html +210 -0
- data/doc/rdoc/files/lib/functor_rb.html +108 -0
- data/doc/rdoc/files/lib/object_rb.html +101 -0
- data/doc/rdoc/fr_class_index.html +29 -0
- data/doc/rdoc/fr_file_index.html +30 -0
- data/doc/rdoc/fr_method_index.html +33 -0
- data/doc/rdoc/index.html +24 -0
- data/doc/rdoc/rdoc-style.css +208 -0
- data/lib/functor.rb +16 -11
- data/test/guards.rb +18 -8
- metadata +31 -2
@@ -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">&</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">"def \#{name}( *args, &block )\nbegin\n\#{klass}.functors[ :\#{name} ].apply( self, *args, &block )\nrescue ArgumentError => e\nbegin\nsuper\nrescue NoMethodError => f\nraise e\nend\nend\nend\n"</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">&</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>
|
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, &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">&</span><span class="ruby-identifier">block</span>)
|
15
|
+
8: <span class="ruby-identifier">mname</span> = <span class="ruby-node">"__instance_exec_#{Thread.current.object_id.abs}"</span>
|
16
|
+
9: <span class="ruby-keyword kw">class</span> <span class="ruby-operator"><<</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">&</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"><<</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‘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 ) # => 25
|
92
|
+
r.repeat( "-" ) # => "- - - - -"
|
93
|
+
r.repeat( 7.3 ) # => 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( &fib ) # => [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
|
+
"guards," 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 "white" and "silver" 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, "demotes" 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 "this would start an infinite loop ..." }
|
161
|
+
given( 0 ) { 0 }
|
162
|
+
given( 1 ) { 1 }
|
163
|
+
# but this will "demote" 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‘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>
|