~ubuntu-branches/ubuntu/intrepid/perl-doc-html/intrepid

« back to all changes in this revision

Viewing changes to Memoize.html

  • Committer: Bazaar Package Importer
  • Author(s): Roberto C. Sanchez
  • Date: 2008-05-17 20:14:19 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080517201419-qgbuogq2ckkdisyi
Tags: 5.10.0-2
Supersede botched upload of 5.10.0-1.

Show diffs side-by-side

added added

removed removed

Lines of Context:
54
54
      <h2>Links:</h2>
55
55
      <ul>
56
56
        <li><a href="http://search.cpan.org">CPAN</a></li>
 
57
        <li><a href="http://www.perl.org">Perl.org</a></li>
57
58
        <li><a href="http://www.perl.com">Perl.com</a></li>
58
 
        <li><a href="http://www.perl.org">Perl.org</a></li>
 
59
        <li><a href="http://perlbuzz.com">Perl Buzz</a></li>
 
60
        <li><a href="http://www.perlfoundation.org/perl5/index.cgi">Perl 5 Wiki</a></li>
 
61
        <li><a href="http://jobs.perl.org">Perl Jobs</a></li>
59
62
        <li><a href="http://www.pm.org">Perl Mongers</a></li>
60
63
        <li><a href="http://www.perlmonks.org">Perl Monks</a></li>
61
64
        <li><a href="http://planet.perl.org">Planet Perl</a></li>
65
68
      <ul>
66
69
        <li>Site maintained by<br><a href="http://perl.jonallen.info">Jon Allen</a>
67
70
            (<a href="http://perl.jonallen.info">JJ</a>)</li>
68
 
        <li class="spaced">Last updated on<br>23 April 2006</li>
 
71
        <li class="spaced">Last updated on<br>23 December 2007</li>
69
72
        <li class="spaced">See the <a href="http://perl.jonallen.info/projects/perldoc">project page</a> for
70
73
        more details</li>
71
74
      </ul>
76
79
    <div id="centerContent">
77
80
      <div id="contentHeader">
78
81
        <div id="contentHeaderLeft"><a href="#" onClick="showLeft()">Show navigation</a></div>
79
 
        <div id="contentHeaderCentre">-- Perl 5.8.8 documentation --</div>
 
82
        <div id="contentHeaderCentre">-- Perl 5.10.0 documentation --</div>
80
83
        <div id="contentHeaderRight"><a href="#" onClick="showRight()">Show toolbar</a></div>
81
84
      </div>
82
85
      <div id="breadCrumbs"><a href="index.html">Home</a> &gt; <a href="index-modules-A.html">Core modules</a> &gt; <a href="index-modules-M.html">M</a> &gt; Memoize</div>
83
86
      <script language="JavaScript">fromSearch();</script>
84
 
      <div id="contentBody"><div class="title_container"><div class="page_title">Memoize</div></div><ul><li><a href="#NAME">NAME</a><li><a href="#SYNOPSIS">SYNOPSIS</a><li><a href="#DESCRIPTION">DESCRIPTION</a><li><a href="#DETAILS">DETAILS</a><li><a href="#OPTIONS">OPTIONS</a><ul><li><a href="#INSTALL">INSTALL</a><li><a href="#NORMALIZER">NORMALIZER</a><li><a href="#'SCALAR_CACHE'%2c-'LIST_CACHE'"><code class="inline">SCALAR_CACHE</code>
85
 
, <code class="inline">LIST_CACHE</code>
86
 
</a></ul><li><a href="#OTHER-FACILITIES">OTHER FACILITIES</a><ul><li><a href="#'unmemoize'"><code class="inline">unmemoize</code>
87
 
</a><li><a href="#'flush_cache'"><code class="inline">flush_cache</code>
 
87
      <div id="contentBody"><div class="title_container"><div class="page_title">Memoize</div></div><ul><li><a href="#NAME">NAME</a><li><a href="#SYNOPSIS">SYNOPSIS</a><li><a href="#DESCRIPTION">DESCRIPTION</a><li><a href="#DETAILS">DETAILS</a><li><a href="#OPTIONS">OPTIONS</a><ul><li><a href="#INSTALL">INSTALL</a><li><a href="#NORMALIZER">NORMALIZER</a><li><a href="#'SCALAR_CACHE'%2c-'LIST_CACHE'"><code class="inline"><span class="w">SCALAR_CACHE</span></code>
 
88
, <code class="inline"><span class="w">LIST_CACHE</span></code>
 
89
</a></ul><li><a href="#OTHER-FACILITIES">OTHER FACILITIES</a><ul><li><a href="#'unmemoize'"><code class="inline"><span class="w">unmemoize</span></code>
 
90
</a><li><a href="#'flush_cache'"><code class="inline"><span class="w">flush_cache</span></code>
88
91
</a></ul><li><a href="#CAVEATS">CAVEATS</a><li><a href="#PERSISTENT-CACHE-SUPPORT">PERSISTENT CACHE SUPPORT</a><li><a href="#EXPIRATION-SUPPORT">EXPIRATION SUPPORT</a><li><a href="#BUGS">BUGS</a><li><a href="#MAILING-LIST">MAILING LIST</a><li><a href="#AUTHOR">AUTHOR</a><li><a href="#COPYRIGHT-AND-LICENSE">COPYRIGHT AND LICENSE</a><li><a href="#THANK-YOU">THANK YOU</a></ul><a name="NAME"></a><h1>NAME</h1>
89
92
<p>Memoize - Make functions faster by trading space for time</p>
90
93
<a name="SYNOPSIS"></a><h1>SYNOPSIS</h1>
91
94
<pre class="verbatim">        <span class="c"># This is the documentation for Memoize 1.01</span>
92
 
        <a class="l_k" href="functions/use.html">use</a> <a class="l_w" href="Memoize.html">Memoize</a><span class="sc">;</span>
 
95
        <a class="l_k" href="functions/use.html">use</a> <span class="w">Memoize</span><span class="sc">;</span>
93
96
        <span class="i">memoize</span><span class="s">(</span><span class="q">&#39;slow_function&#39;</span><span class="s">)</span><span class="sc">;</span>
94
 
        <span class="i">slow_function</span><span class="s">(</span>arguments<span class="s">)</span><span class="sc">;</span>    <span class="c"># Is faster than it was before</span></pre>
 
97
        <span class="i">slow_function</span><span class="s">(</span><span class="w">arguments</span><span class="s">)</span><span class="sc">;</span>    <span class="c"># Is faster than it was before</span></pre>
95
98
<p>This is normally all you need to know.  However, many options are available:</p>
96
 
<pre class="verbatim">  <span class="i">memoize</span><span class="s">(</span>function<span class="cm">,</span> options...<span class="s">)</span><span class="sc">;</span></pre>
 
99
<pre class="verbatim">  <span class="i">memoize</span><span class="s">(</span><span class="w">function</span><span class="cm">,</span> <span class="w">options</span>...<span class="s">)</span><span class="sc">;</span></pre>
97
100
<p>Options include:</p>
98
 
<pre class="verbatim">  NORMALIZER <span class="cm">=&gt;</span> function
99
 
        INSTALL <span class="cm">=&gt;</span> new_name</pre>
100
 
<pre class="verbatim">  SCALAR_CACHE <span class="cm">=&gt;</span> <span class="q">&#39;MEMORY&#39;</span>
101
 
        SCALAR_CACHE <span class="cm">=&gt;</span> <span class="s">[</span><span class="q">&#39;HASH&#39;</span><span class="cm">,</span> \<span class="i">%cache_hash</span> <span class="s">]</span>
102
 
        SCALAR_CACHE <span class="cm">=&gt;</span> <span class="q">&#39;FAULT&#39;</span>
103
 
        SCALAR_CACHE <span class="cm">=&gt;</span> <span class="q">&#39;MERGE&#39;</span></pre>
104
 
<pre class="verbatim">  LIST_CACHE <span class="cm">=&gt;</span> <span class="q">&#39;MEMORY&#39;</span>
105
 
        LIST_CACHE <span class="cm">=&gt;</span> <span class="s">[</span><span class="q">&#39;HASH&#39;</span><span class="cm">,</span> \<span class="i">%cache_hash</span> <span class="s">]</span>
106
 
        LIST_CACHE <span class="cm">=&gt;</span> <span class="q">&#39;FAULT&#39;</span>
107
 
        LIST_CACHE <span class="cm">=&gt;</span> <span class="q">&#39;MERGE&#39;</span></pre>
 
101
<pre class="verbatim">  <span class="w">NORMALIZER</span> <span class="cm">=&gt;</span> <span class="w">function</span>
 
102
        <span class="w">INSTALL</span> <span class="cm">=&gt;</span> <span class="w">new_name</span></pre>
 
103
<pre class="verbatim">  <span class="w">SCALAR_CACHE</span> <span class="cm">=&gt;</span> <span class="q">&#39;MEMORY&#39;</span>
 
104
        <span class="w">SCALAR_CACHE</span> <span class="cm">=&gt;</span> <span class="s">[</span><span class="q">&#39;HASH&#39;</span><span class="cm">,</span> \<span class="i">%cache_hash</span> <span class="s">]</span>
 
105
        <span class="w">SCALAR_CACHE</span> <span class="cm">=&gt;</span> <span class="q">&#39;FAULT&#39;</span>
 
106
        <span class="w">SCALAR_CACHE</span> <span class="cm">=&gt;</span> <span class="q">&#39;MERGE&#39;</span></pre>
 
107
<pre class="verbatim">  <span class="w">LIST_CACHE</span> <span class="cm">=&gt;</span> <span class="q">&#39;MEMORY&#39;</span>
 
108
        <span class="w">LIST_CACHE</span> <span class="cm">=&gt;</span> <span class="s">[</span><span class="q">&#39;HASH&#39;</span><span class="cm">,</span> \<span class="i">%cache_hash</span> <span class="s">]</span>
 
109
        <span class="w">LIST_CACHE</span> <span class="cm">=&gt;</span> <span class="q">&#39;FAULT&#39;</span>
 
110
        <span class="w">LIST_CACHE</span> <span class="cm">=&gt;</span> <span class="q">&#39;MERGE&#39;</span></pre>
108
111
<a name="DESCRIPTION"></a><h1>DESCRIPTION</h1>
109
112
<p>`Memoizing' a function makes it faster by trading space for time.  It
110
113
does this by caching the return values of the function in a table.
111
 
If you call the function again with the same arguments, <code class="inline">memoize</code>
 
114
If you call the function again with the same arguments, <code class="inline"><span class="w">memoize</span></code>
112
115
 
113
116
jumps in and gives you the value out of the table, instead of letting
114
117
the function compute the value all over again.</p>
152
155
          <span class="s">}</span>
153
156
        <span class="s">}</span></pre>
154
157
<p>Or you could use this module, like this:</p>
155
 
<pre class="verbatim">  <a class="l_k" href="functions/use.html">use</a> <a class="l_w" href="Memoize.html">Memoize</a><span class="sc">;</span>
 
158
<pre class="verbatim">  <a class="l_k" href="functions/use.html">use</a> <span class="w">Memoize</span><span class="sc">;</span>
156
159
        <span class="i">memoize</span><span class="s">(</span><span class="q">&#39;fib&#39;</span><span class="s">)</span><span class="sc">;</span></pre>
157
160
<pre class="verbatim">  <span class="c"># Rest of the fib function just like the original version.</span></pre>
158
161
<p>This makes it easy to turn memoizing on and off.</p>
163
166
this:</p>
164
167
<pre class="verbatim">    for <span class="s">(</span><span class="i">$direction</span> = <span class="n">0</span><span class="sc">;</span> <span class="i">$direction</span> &lt; <span class="n">300</span><span class="sc">;</span> <span class="i">$direction</span>++<span class="s">)</span> <span class="s">{</span>
165
168
      <span class="c"># Figure out which object is in direction $direction</span>
166
 
      <span class="i">$color</span> = <span class="i">$object</span>-&gt;{color}<span class="sc">;</span>
 
169
      <span class="i">$color</span> = <span class="i">$object</span>-&gt;{<span class="w">color</span>}<span class="sc">;</span>
167
170
      <span class="s">(</span><span class="i">$r</span><span class="cm">,</span> <span class="i">$g</span><span class="cm">,</span> <span class="i">$b</span><span class="s">)</span> = <span class="i">@</span>{<span class="i">&amp;ColorToRGB</span><span class="s">(</span><span class="i">$color</span><span class="s">)</span>}<span class="sc">;</span>
168
171
      ...
169
172
    <span class="s">}</span></pre>
170
173
<p>Since there are relatively few objects in a picture, there are only a
171
174
few colors, which get looked up over and over again.  Memoizing
172
 
<code class="inline">ColorToRGB</code>
 
175
<code class="inline"><span class="w">ColorToRGB</span></code>
173
176
 sped up the program by several percent.</p>
174
177
<a name="DETAILS"></a><h1>DETAILS</h1>
175
 
<p>This module exports exactly one function, <code class="inline">memoize</code>
 
178
<p>This module exports exactly one function, <code class="inline"><span class="w">memoize</span></code>
176
179
.  The rest of the
177
180
functions in this package are None of Your Business.</p>
178
181
<p>You should say</p>
179
 
<pre class="verbatim">  <span class="i">memoize</span><span class="s">(</span>function<span class="s">)</span></pre>
180
 
<p>where <code class="inline">function</code>
 
182
<pre class="verbatim">  <span class="i">memoize</span><span class="s">(</span><span class="w">function</span><span class="s">)</span></pre>
 
183
<p>where <code class="inline"><span class="w">function</span></code>
181
184
 is the name of the function you want to memoize, or
182
 
a reference to it.  <code class="inline">memoize</code>
 
185
a reference to it.  <code class="inline"><span class="w">memoize</span></code>
183
186
 returns a reference to the new,
184
187
memoized version of the function, or <code class="inline"><a class="l_k" href="functions/undef.html">undef</a></code> on a non-fatal error.
185
188
At present, there are no non-fatal errors, but there might be some in
186
189
the future.</p>
187
 
<p>If <code class="inline">function</code>
188
 
 was the name of a function, then <code class="inline">memoize</code>
 
190
<p>If <code class="inline"><span class="w">function</span></code>
 
191
 was the name of a function, then <code class="inline"><span class="w">memoize</span></code>
189
192
 hides the
190
193
old version and installs the new memoized version under the old name,
191
194
so that <code class="inline"><span class="i">&amp;function</span><span class="s">(</span>...<span class="s">)</span></code>
192
195
 actually invokes the memoized version.</p>
193
196
<a name="OPTIONS"></a><h1>OPTIONS</h1>
194
 
<p>There are some optional options you can pass to <code class="inline">memoize</code>
 
197
<p>There are some optional options you can pass to <code class="inline"><span class="w">memoize</span></code>
195
198
 to change
196
 
the way it behaves a little.  To supply options, invoke <code class="inline">memoize</code>
 
199
the way it behaves a little.  To supply options, invoke <code class="inline"><span class="w">memoize</span></code>
197
200
 
198
201
like this:</p>
199
 
<pre class="verbatim">  <span class="i">memoize</span><span class="s">(</span>function<span class="cm">,</span> NORMALIZER <span class="cm">=&gt;</span> function<span class="cm">,</span>
200
 
                          INSTALL <span class="cm">=&gt;</span> newname<span class="cm">,</span>
201
 
                          SCALAR_CACHE <span class="cm">=&gt;</span> option<span class="cm">,</span>
202
 
                          LIST_CACHE <span class="cm">=&gt;</span> option
 
202
<pre class="verbatim">  <span class="i">memoize</span><span class="s">(</span><span class="w">function</span><span class="cm">,</span> <span class="w">NORMALIZER</span> <span class="cm">=&gt;</span> <span class="w">function</span><span class="cm">,</span>
 
203
                          <span class="w">INSTALL</span> <span class="cm">=&gt;</span> <span class="w">newname</span><span class="cm">,</span>
 
204
                          <span class="w">SCALAR_CACHE</span> <span class="cm">=&gt;</span> <span class="w">option</span><span class="cm">,</span>
 
205
                          <span class="w">LIST_CACHE</span> <span class="cm">=&gt;</span> <span class="w">option</span>
203
206
                         <span class="s">)</span><span class="sc">;</span></pre>
204
207
<p>Each of these options is optional; you can include some, all, or none
205
208
of them.</p>
206
209
<a name="INSTALL"></a><h2>INSTALL</h2>
207
 
<p>If you supply a function name with <code class="inline">INSTALL</code>
 
210
<p>If you supply a function name with <code class="inline"><span class="w">INSTALL</span></code>
208
211
, memoize will install
209
212
the new, memoized version of the function under the name you give.
210
 
For example, </p>
211
 
<pre class="verbatim">  <span class="i">memoize</span><span class="s">(</span><span class="q">&#39;fib&#39;</span><span class="cm">,</span> INSTALL <span class="cm">=&gt;</span> <span class="q">&#39;fastfib&#39;</span><span class="s">)</span></pre>
212
 
<p>installs the memoized version of <code class="inline">fib</code>
213
 
 as <code class="inline">fastfib</code>
 
213
For example,</p>
 
214
<pre class="verbatim">  <span class="i">memoize</span><span class="s">(</span><span class="q">&#39;fib&#39;</span><span class="cm">,</span> <span class="w">INSTALL</span> <span class="cm">=&gt;</span> <span class="q">&#39;fastfib&#39;</span><span class="s">)</span></pre>
 
215
<p>installs the memoized version of <code class="inline"><span class="w">fib</span></code>
 
216
 as <code class="inline"><span class="w">fastfib</span></code>
214
217
; without the
215
 
<code class="inline">INSTALL</code>
216
 
 option it would have replaced the old <code class="inline">fib</code>
 
218
<code class="inline"><span class="w">INSTALL</span></code>
 
219
 option it would have replaced the old <code class="inline"><span class="w">fib</span></code>
217
220
 with the
218
 
memoized version.  </p>
219
 
<p>To prevent <code class="inline">memoize</code>
 
221
memoized version.</p>
 
222
<p>To prevent <code class="inline"><span class="w">memoize</span></code>
220
223
 from installing the memoized version anywhere, use
221
 
<code class="inline">INSTALL <span class="cm">=&gt;</span> <a class="l_k" href="functions/undef.html">undef</a></code>
 
224
<code class="inline"><span class="w">INSTALL</span> <span class="cm">=&gt;</span> <a class="l_k" href="functions/undef.html">undef</a></code>
222
225
.</p>
223
226
<a name="NORMALIZER"></a><h2>NORMALIZER</h2>
224
227
<p>Suppose your function looks like this:</p>
229
232
          $hash{B} ||= 2;  # B defaults to 2
230
233
          $hash{C} ||= 7;  # C defaults to 7</pre><pre class="verbatim">          # Do something with $a, %hash
231
234
        }</pre><p>Now, the following calls to your function are all completely equivalent:</p>
232
 
<pre class="verbatim">  <span class="i">f</span><span class="s">(</span>OUCH<span class="s">)</span><span class="sc">;</span>
233
 
        <span class="i">f</span><span class="s">(</span>OUCH<span class="cm">,</span> <a class="l_w" href="B.html">B</a> <span class="cm">=&gt;</span> <span class="n">2</span><span class="s">)</span><span class="sc">;</span>
234
 
        <span class="i">f</span><span class="s">(</span>OUCH<span class="cm">,</span> C <span class="cm">=&gt;</span> <span class="n">7</span><span class="s">)</span><span class="sc">;</span>
235
 
        <span class="i">f</span><span class="s">(</span>OUCH<span class="cm">,</span> <a class="l_w" href="B.html">B</a> <span class="cm">=&gt;</span> <span class="n">2</span><span class="cm">,</span> C <span class="cm">=&gt;</span> <span class="n">7</span><span class="s">)</span><span class="sc">;</span>
236
 
        <span class="i">f</span><span class="s">(</span>OUCH<span class="cm">,</span> C <span class="cm">=&gt;</span> <span class="n">7</span><span class="cm">,</span> <a class="l_w" href="B.html">B</a> <span class="cm">=&gt;</span> <span class="n">2</span><span class="s">)</span><span class="sc">;</span>
237
 
        <span class="s">(</span>etc.<span class="s">)</span></pre>
238
 
<p>However, unless you tell <code class="inline"><a class="l_w" href="Memoize.html">Memoize</a></code> that these calls are equivalent,
 
235
<pre class="verbatim">  <span class="i">f</span><span class="s">(</span><span class="w">OUCH</span><span class="s">)</span><span class="sc">;</span>
 
236
        <span class="i">f</span><span class="s">(</span><span class="w">OUCH</span><span class="cm">,</span> <span class="w">B</span> <span class="cm">=&gt;</span> <span class="n">2</span><span class="s">)</span><span class="sc">;</span>
 
237
        <span class="i">f</span><span class="s">(</span><span class="w">OUCH</span><span class="cm">,</span> <span class="w">C</span> <span class="cm">=&gt;</span> <span class="n">7</span><span class="s">)</span><span class="sc">;</span>
 
238
        <span class="i">f</span><span class="s">(</span><span class="w">OUCH</span><span class="cm">,</span> <span class="w">B</span> <span class="cm">=&gt;</span> <span class="n">2</span><span class="cm">,</span> <span class="w">C</span> <span class="cm">=&gt;</span> <span class="n">7</span><span class="s">)</span><span class="sc">;</span>
 
239
        <span class="i">f</span><span class="s">(</span><span class="w">OUCH</span><span class="cm">,</span> <span class="w">C</span> <span class="cm">=&gt;</span> <span class="n">7</span><span class="cm">,</span> <span class="w">B</span> <span class="cm">=&gt;</span> <span class="n">2</span><span class="s">)</span><span class="sc">;</span>
 
240
        <span class="s">(</span><span class="w">etc</span>.<span class="s">)</span></pre>
 
241
<p>However, unless you tell <code class="inline"><span class="w">Memoize</span></code>
 
242
 that these calls are equivalent,
239
243
it will not know that, and it will compute the values for these
240
244
invocations of your function separately, and store them separately.</p>
241
 
<p>To prevent this, supply a <code class="inline">NORMALIZER</code>
 
245
<p>To prevent this, supply a <code class="inline"><span class="w">NORMALIZER</span></code>
242
246
 function that turns the
243
247
program arguments into a string in a way that equivalent arguments
244
 
turn into the same string.  A <code class="inline">NORMALIZER</code>
245
 
 function for <code class="inline">f</code>
 
248
turn into the same string.  A <code class="inline"><span class="w">NORMALIZER</span></code>
 
249
 function for <code class="inline"><span class="w">f</span></code>
246
250
 above
247
251
might look like this:</p>
248
252
<pre class="verbatim">  sub normalize_f {
250
254
          my %hash = @_;
251
255
          $hash{B} ||= 2;
252
256
          $hash{C} ||= 7;</pre><pre class="verbatim">     join(',', $a, map ($_ =&gt; $hash{$_}) sort keys %hash);
253
 
        }</pre><p>Each of the argument lists above comes out of the <code class="inline">normalize_f</code>
 
257
        }</pre><p>Each of the argument lists above comes out of the <code class="inline"><span class="w">normalize_f</span></code>
254
258
 
255
259
function looking exactly the same, like this:</p>
256
 
<pre class="verbatim">  OUCH<span class="cm">,</span><a class="l_w" href="B.html">B</a><span class="cm">,</span><span class="n">2</span><span class="cm">,</span>C<span class="cm">,</span><span class="n">7</span></pre>
257
 
<p>You would tell <code class="inline"><a class="l_w" href="Memoize.html">Memoize</a></code> to use this normalizer this way:</p>
258
 
<pre class="verbatim">  <span class="i">memoize</span><span class="s">(</span><span class="q">&#39;f&#39;</span><span class="cm">,</span> NORMALIZER <span class="cm">=&gt;</span> <span class="q">&#39;normalize_f&#39;</span><span class="s">)</span><span class="sc">;</span></pre>
259
 
<p><code class="inline">memoize</code>
 
260
<pre class="verbatim">  <span class="w">OUCH</span><span class="cm">,</span><span class="w">B</span><span class="cm">,</span><span class="n">2</span><span class="cm">,</span><span class="w">C</span><span class="cm">,</span><span class="n">7</span></pre>
 
261
<p>You would tell <code class="inline"><span class="w">Memoize</span></code>
 
262
 to use this normalizer this way:</p>
 
263
<pre class="verbatim">  <span class="i">memoize</span><span class="s">(</span><span class="q">&#39;f&#39;</span><span class="cm">,</span> <span class="w">NORMALIZER</span> <span class="cm">=&gt;</span> <span class="q">&#39;normalize_f&#39;</span><span class="s">)</span><span class="sc">;</span></pre>
 
264
<p><code class="inline"><span class="w">memoize</span></code>
260
265
 knows that if the normalized version of the arguments is
261
266
the same for two argument lists, then it can safely look up the value
262
267
that it computed for one argument list and return it as the result of
273
278
<p>Since hash keys are strings, the default normalizer will not
274
279
distinguish between <code class="inline"><a class="l_k" href="functions/undef.html">undef</a></code> and the empty string.  It also won't work
275
280
when the function's arguments are references.  For example, consider a
276
 
function <code class="inline">g</code>
 
281
function <code class="inline"><span class="w">g</span></code>
277
282
 which gets two arguments: A number, and a reference to
278
283
an array of numbers:</p>
279
284
<pre class="verbatim">  <span class="i">g</span><span class="s">(</span><span class="n">13</span><span class="cm">,</span> <span class="s">[</span><span class="n">1</span><span class="cm">,</span><span class="n">2</span><span class="cm">,</span><span class="n">3</span><span class="cm">,</span><span class="n">4</span><span class="cm">,</span><span class="n">5</span><span class="cm">,</span><span class="n">6</span><span class="cm">,</span><span class="n">7</span><span class="s">]</span><span class="s">)</span><span class="sc">;</span></pre>
281
286
<code class="inline"><span class="q">&quot;13\034ARRAY(0x436c1f)&quot;</span></code>
282
287
.  That would be all right, except that a
283
288
subsequent array of numbers might be stored at a different location
284
 
even though it contains the same data.  If this happens, <code class="inline"><a class="l_w" href="Memoize.html">Memoize</a></code>
 
289
even though it contains the same data.  If this happens, <code class="inline"><span class="w">Memoize</span></code>
 
290
 
285
291
will think that the arguments are different, even though they are
286
292
equivalent.  In this case, a normalizer like this is appropriate:</p>
287
293
<pre class="verbatim"><a name="normalize"></a>  sub <span class="m">normalize</span> <span class="s">{</span> <a class="l_k" href="functions/join.html">join</a> <span class="q">&#39; &#39;</span><span class="cm">,</span> <span class="i">$_</span>[<span class="n">0</span>]<span class="cm">,</span> <span class="i">@</span>{<span class="i">$_</span>[<span class="n">1</span>]} <span class="s">}</span></pre>
299
305
          } 
300
306
          return $line;
301
307
        }</pre><p>At 10:23, this function generates the 10th line of a data file; at
302
 
3:45 PM it generates the 15th line instead.  By default, <code class="inline"><a class="l_w" href="Memoize.html">Memoize</a></code>
 
308
3:45 PM it generates the 15th line instead.  By default, <code class="inline"><span class="w">Memoize</span></code>
 
309
 
303
310
will only see the $problem_type argument.  To fix this, include the
304
311
current hour in the normalizer:</p>
305
312
<pre class="verbatim"><a name="normalize"></a>        sub <span class="m">normalize</span> <span class="s">{</span> <a class="l_k" href="functions/join.html">join</a> <span class="q">&#39; &#39;</span><span class="cm">,</span> <span class="s">(</span><a class="l_k" href="functions/localtime.html">localtime</a><span class="s">)</span>[<span class="n">2</span>]<span class="cm">,</span> <span class="i">@_</span> <span class="s">}</span></pre>
309
316
would in scalar context, you can have the normalizer function select
310
317
its behavior based on the results of <code class="inline"><a class="l_k" href="functions/wantarray.html">wantarray</a></code>.  Even if called in
311
318
a list context, a normalizer should still return a single string.</p>
312
 
<a name="'SCALAR_CACHE'%2c-'LIST_CACHE'"></a><h2><code class="inline">SCALAR_CACHE</code>
313
 
, <code class="inline">LIST_CACHE</code>
 
319
<a name="'SCALAR_CACHE'%2c-'LIST_CACHE'"></a><h2><code class="inline"><span class="w">SCALAR_CACHE</span></code>
 
320
, <code class="inline"><span class="w">LIST_CACHE</span></code>
314
321
</h2>
315
 
<p>Normally, <code class="inline"><a class="l_w" href="Memoize.html">Memoize</a></code> caches your function's return values into an
 
322
<p>Normally, <code class="inline"><span class="w">Memoize</span></code>
 
323
 caches your function's return values into an
316
324
ordinary Perl hash variable.  However, you might like to have the
317
325
values cached on the disk, so that they persist from one run of your
318
326
program to the next, or you might like to associate some other
319
327
interesting semantics with the cached values.</p>
320
 
<p>There's a slight complication under the hood of <code class="inline"><a class="l_w" href="Memoize.html">Memoize</a></code>: There are
 
328
<p>There's a slight complication under the hood of <code class="inline"><span class="w">Memoize</span></code>
 
329
: There are
321
330
actually <i>two</i> caches, one for scalar values and one for list values.
322
331
When your function is called in scalar context, its return value is
323
332
cached in one hash, and when your function is called in list context,
324
333
its value is cached in the other hash.  You can control the caching
325
334
behavior of both contexts independently with these options.</p>
326
 
<p>The argument to <code class="inline">LIST_CACHE</code>
327
 
 or <code class="inline">SCALAR_CACHE</code>
 
335
<p>The argument to <code class="inline"><span class="w">LIST_CACHE</span></code>
 
336
 or <code class="inline"><span class="w">SCALAR_CACHE</span></code>
328
337
 must either be one of
329
338
the following four strings:</p>
330
 
<pre class="verbatim">  MEMORY
331
 
        FAULT
332
 
        MERGE
333
 
        HASH</pre>
 
339
<pre class="verbatim">  <span class="w">MEMORY</span>
 
340
        <span class="w">FAULT</span>
 
341
        <span class="w">MERGE</span>
 
342
        <span class="w">HASH</span></pre>
334
343
<p>or else it must be a reference to a list whose first element is one of
335
 
these four strings, such as <code class="inline"><span class="s">[</span>HASH<span class="cm">,</span> arguments...<span class="s">]</span></code>
 
344
these four strings, such as <code class="inline"><span class="s">[</span><span class="w">HASH</span><span class="cm">,</span> <span class="w">arguments</span>...<span class="s">]</span></code>
336
345
.</p>
337
346
<ul>
338
 
<li><a name="'MEMORY'"></a><b><code class="inline">MEMORY</code>
 
347
<li><a name="'MEMORY'"></a><b><code class="inline"><span class="w">MEMORY</span></code>
339
348
</b>
340
 
<p><code class="inline">MEMORY</code>
 
349
<p><code class="inline"><span class="w">MEMORY</span></code>
341
350
 means that return values from the function will be cached in
342
351
an ordinary Perl hash variable.  The hash variable will not persist
343
352
after the program exits.  This is the default.</p>
344
353
</li>
345
 
<li><a name="'HASH'"></a><b><code class="inline">HASH</code>
 
354
<li><a name="'HASH'"></a><b><code class="inline"><span class="w">HASH</span></code>
346
355
</b>
347
 
<p><code class="inline">HASH</code>
 
356
<p><code class="inline"><span class="w">HASH</span></code>
348
357
 allows you to specify that a particular hash that you supply
349
358
will be used as the cache.  You can tie this hash beforehand to give
350
359
it any behavior you want.</p>
351
360
<p>A tied hash can have any semantics at all.  It is typically tied to an
352
361
on-disk database, so that cached values are stored in the database and
353
362
retrieved from it again when needed, and the disk file typically
354
 
persists after your program has exited.  See <code class="inline">perltie</code>
 
363
persists after your program has exited.  See <code class="inline"><span class="w">perltie</span></code>
355
364
 for more
356
365
complete details about <code class="inline"><a class="l_k" href="functions/tie.html">tie</a></code>.</p>
357
366
<p>A typical example is:</p>
358
 
<pre class="verbatim">        <a class="l_k" href="functions/use.html">use</a> <a class="l_w" href="DB_File.html">DB_File</a><span class="sc">;</span>
359
 
        <a class="l_k" href="functions/tie.html">tie</a> <a class="l_k" href="functions/my.html">my</a> <span class="i">%cache</span> <span class="cm">=&gt;</span> <span class="q">&#39;DB_File&#39;</span><span class="cm">,</span> <span class="i">$filename</span><span class="cm">,</span> O_RDWR|O_CREAT<span class="cm">,</span> <span class="n">0666</span><span class="sc">;</span>
360
 
        memoize <span class="q">&#39;function&#39;</span><span class="cm">,</span> SCALAR_CACHE <span class="cm">=&gt;</span> <span class="s">[</span>HASH <span class="cm">=&gt;</span> \<span class="i">%cache</span><span class="s">]</span><span class="sc">;</span></pre>
361
 
<p>This has the effect of storing the cache in a <code class="inline"><a class="l_w" href="DB_File.html">DB_File</a></code> database
 
367
<pre class="verbatim">        <a class="l_k" href="functions/use.html">use</a> <span class="w">DB_File</span><span class="sc">;</span>
 
368
        <a class="l_k" href="functions/tie.html">tie</a> <a class="l_k" href="functions/my.html">my</a> <span class="i">%cache</span> <span class="cm">=&gt;</span> <span class="q">&#39;DB_File&#39;</span><span class="cm">,</span> <span class="i">$filename</span><span class="cm">,</span> <span class="w">O_RDWR</span>|<span class="w">O_CREAT</span><span class="cm">,</span> <span class="n">0666</span><span class="sc">;</span>
 
369
        <span class="w">memoize</span> <span class="q">&#39;function&#39;</span><span class="cm">,</span> <span class="w">SCALAR_CACHE</span> <span class="cm">=&gt;</span> <span class="s">[</span><span class="w">HASH</span> <span class="cm">=&gt;</span> \<span class="i">%cache</span><span class="s">]</span><span class="sc">;</span></pre>
 
370
<p>This has the effect of storing the cache in a <code class="inline"><span class="w">DB_File</span></code>
 
371
 database
362
372
whose name is in <code class="inline"><span class="i">$filename</span></code>
363
373
.  The cache will persist after the
364
374
program has exited.  Next time the program runs, it will find the
368
378
come to run your real program the memoized function will be fast
369
379
because all its results have been precomputed.</p>
370
380
</li>
371
 
<li><a name="'TIE'"></a><b><code class="inline">TIE</code>
 
381
<li><a name="'TIE'"></a><b><code class="inline"><span class="w">TIE</span></code>
372
382
</b>
373
383
<p>This option is no longer supported.  It is still documented only to
374
384
aid in the debugging of old programs that use it.  Old programs should
375
 
be converted to use the <code class="inline">HASH</code>
 
385
be converted to use the <code class="inline"><span class="w">HASH</span></code>
376
386
 option instead.</p>
377
 
<pre class="verbatim">        memoize ... <span class="s">[</span>TIE<span class="cm">,</span> PACKAGE<span class="cm">,</span> ARGS...<span class="s">]</span></pre>
 
387
<pre class="verbatim">        <span class="w">memoize</span> ... <span class="s">[</span><span class="w">TIE</span><span class="cm">,</span> <span class="w">PACKAGE</span><span class="cm">,</span> <span class="w">ARGS</span>...<span class="s">]</span></pre>
378
388
<p>is merely a shortcut for</p>
379
 
<pre class="verbatim">        <a class="l_k" href="functions/require.html">require</a> PACKAGE<span class="sc">;</span>
 
389
<pre class="verbatim">        <a class="l_k" href="functions/require.html">require</a> <span class="w">PACKAGE</span><span class="sc">;</span>
380
390
        <span class="s">{</span> <a class="l_k" href="functions/my.html">my</a> <span class="i">%cache</span><span class="sc">;</span>
381
 
          <a class="l_k" href="functions/tie.html">tie</a> <span class="i">%cache</span><span class="cm">,</span> PACKAGE<span class="cm">,</span> ARGS...<span class="sc">;</span>
 
391
          <a class="l_k" href="functions/tie.html">tie</a> <span class="i">%cache</span><span class="cm">,</span> <span class="w">PACKAGE</span><span class="cm">,</span> <span class="w">ARGS</span>...<span class="sc">;</span>
382
392
        <span class="s">}</span>
383
 
        memoize ... <span class="s">[</span>HASH <span class="cm">=&gt;</span> \<span class="i">%cache</span><span class="s">]</span><span class="sc">;</span></pre>
 
393
        <span class="w">memoize</span> ... <span class="s">[</span><span class="w">HASH</span> <span class="cm">=&gt;</span> \<span class="i">%cache</span><span class="s">]</span><span class="sc">;</span></pre>
384
394
</li>
385
 
<li><a name="'FAULT'"></a><b><code class="inline">FAULT</code>
 
395
<li><a name="'FAULT'"></a><b><code class="inline"><span class="w">FAULT</span></code>
386
396
</b>
387
 
<p><code class="inline">FAULT</code>
 
397
<p><code class="inline"><span class="w">FAULT</span></code>
388
398
 means that you never expect to call the function in scalar
389
 
(or list) context, and that if <code class="inline"><a class="l_w" href="Memoize.html">Memoize</a></code> detects such a call, it
 
399
(or list) context, and that if <code class="inline"><span class="w">Memoize</span></code>
 
400
 detects such a call, it
390
401
should abort the program.  The error message is one of</p>
391
402
<pre class="verbatim">  `foo' function called in forbidden list context at line ...
392
403
        `foo' function called in forbidden scalar context at line ...</pre></li>
393
 
<li><a name="'MERGE'"></a><b><code class="inline">MERGE</code>
 
404
<li><a name="'MERGE'"></a><b><code class="inline"><span class="w">MERGE</span></code>
394
405
</b>
395
 
<p><code class="inline">MERGE</code>
 
406
<p><code class="inline"><span class="w">MERGE</span></code>
396
407
 normally means the function does not distinguish between list
397
408
and sclar context, and that return values in both contexts should be
398
 
stored together.  <code class="inline">LIST_CACHE <span class="cm">=&gt;</span> MERGE</code>
 
409
stored together.  <code class="inline"><span class="w">LIST_CACHE</span> <span class="cm">=&gt;</span> <span class="w">MERGE</span></code>
399
410
 means that list context
400
411
return values should be stored in the same hash that is used for
401
 
scalar context returns, and <code class="inline">SCALAR_CACHE <span class="cm">=&gt;</span> MERGE</code>
 
412
scalar context returns, and <code class="inline"><span class="w">SCALAR_CACHE</span> <span class="cm">=&gt;</span> <span class="w">MERGE</span></code>
402
413
 means the
403
 
same, mutatis mutandis.  It is an error to specify <code class="inline">MERGE</code>
 
414
same, mutatis mutandis.  It is an error to specify <code class="inline"><span class="w">MERGE</span></code>
404
415
 for both,
405
416
but it probably does something useful.</p>
406
417
<p>Consider this function:</p>
407
418
<pre class="verbatim"><a name="pi"></a> sub <span class="m">pi</span> <span class="s">{</span> <span class="n">3</span><span class="sc">;</span> <span class="s">}</span></pre>
408
 
<p>Normally, the following code will result in two calls to <code class="inline">pi</code>
 
419
<p>Normally, the following code will result in two calls to <code class="inline"><span class="w">pi</span></code>
409
420
:</p>
410
421
<pre class="verbatim">    <span class="i">$x</span> = <span class="i">pi</span><span class="s">(</span><span class="s">)</span><span class="sc">;</span>
411
422
    <span class="s">(</span><span class="i">$y</span><span class="s">)</span> = <span class="i">pi</span><span class="s">(</span><span class="s">)</span><span class="sc">;</span>
414
425
 in the scalar cache; the second
415
426
caches the list <code class="inline"><span class="s">(</span><span class="n">3</span><span class="s">)</span></code>
416
427
 in the list cache.  The third call doesn't call
417
 
the real <code class="inline">pi</code>
 
428
the real <code class="inline"><span class="w">pi</span></code>
418
429
 function; it gets the value from the scalar cache.</p>
419
 
<p>Obviously, the second call to <code class="inline">pi</code>
 
430
<p>Obviously, the second call to <code class="inline"><span class="w">pi</span></code>
420
431
 is a waste of time, and storing
421
 
its return value is a waste of space.  Specifying <code class="inline">LIST_CACHE <span class="cm">=&gt;</span>
422
 
MERGE</code>
423
 
 will make <code class="inline">memoize</code>
 
432
its return value is a waste of space.  Specifying <code class="inline"><span class="w">LIST_CACHE</span> <span class="cm">=&gt;</span>
 
433
<span class="w">MERGE</span></code>
 
434
 will make <code class="inline"><span class="w">memoize</span></code>
424
435
 use the same cache for scalar and list
425
436
context return values, so that the second call uses the scalar cache
426
 
that was populated by the first call.  <code class="inline">pi</code>
 
437
that was populated by the first call.  <code class="inline"><span class="w">pi</span></code>
427
438
 ends up being called only
428
439
once, and both subsequent calls return <code class="inline"><span class="n">3</span></code>
429
440
 from the cache, regardless
430
441
of the calling context.</p>
431
 
<p>Another use for <code class="inline">MERGE</code>
 
442
<p>Another use for <code class="inline"><span class="w">MERGE</span></code>
432
443
 is when you want both kinds of return values
433
444
stored in the same disk file; this saves you from having to deal with
434
445
two disk files instead of one.  You can use a normalizer function to
435
446
keep the two sets of return values separate.  For example:</p>
436
447
<pre class="verbatim">        <a class="l_k" href="functions/tie.html">tie</a> <a class="l_k" href="functions/my.html">my</a> <span class="i">%cache</span> <span class="cm">=&gt;</span> <span class="q">&#39;MLDBM&#39;</span><span class="cm">,</span> <span class="q">&#39;DB_File&#39;</span><span class="cm">,</span> <span class="i">$filename</span><span class="cm">,</span> ...<span class="sc">;</span></pre>
437
 
<pre class="verbatim">  memoize <span class="q">&#39;myfunc&#39;</span><span class="cm">,</span>
438
 
          NORMALIZER <span class="cm">=&gt;</span> <span class="q">&#39;n&#39;</span><span class="cm">,</span>
439
 
          SCALAR_CACHE <span class="cm">=&gt;</span> <span class="s">[</span>HASH <span class="cm">=&gt;</span> \<span class="i">%cache</span><span class="s">]</span><span class="cm">,</span>
440
 
          LIST_CACHE <span class="cm">=&gt;</span> MERGE<span class="cm">,</span>
 
448
<pre class="verbatim">  <span class="w">memoize</span> <span class="q">&#39;myfunc&#39;</span><span class="cm">,</span>
 
449
          <span class="w">NORMALIZER</span> <span class="cm">=&gt;</span> <span class="q">&#39;n&#39;</span><span class="cm">,</span>
 
450
          <span class="w">SCALAR_CACHE</span> <span class="cm">=&gt;</span> <span class="s">[</span><span class="w">HASH</span> <span class="cm">=&gt;</span> \<span class="i">%cache</span><span class="s">]</span><span class="cm">,</span>
 
451
          <span class="w">LIST_CACHE</span> <span class="cm">=&gt;</span> <span class="w">MERGE</span><span class="cm">,</span>
441
452
        <span class="sc">;</span></pre>
442
453
<pre class="verbatim"><a name="n"></a>  sub <span class="m">n</span> <span class="s">{</span>
443
454
          <a class="l_k" href="functions/my.html">my</a> <span class="i">$context</span> = <a class="l_k" href="functions/wantarray.html">wantarray</a><span class="s">(</span><span class="s">)</span> ? <span class="q">&#39;L&#39;</span> <span class="co">:</span> <span class="q">&#39;S&#39;</span><span class="sc">;</span>
452
463
</li>
453
464
</ul>
454
465
<a name="OTHER-FACILITIES"></a><h1>OTHER FACILITIES</h1>
455
 
<a name="'unmemoize'"></a><h2><code class="inline">unmemoize</code>
 
466
<a name="'unmemoize'"></a><h2><code class="inline"><span class="w">unmemoize</span></code>
456
467
</h2>
457
 
<p>There's an <code class="inline">unmemoize</code>
 
468
<p>There's an <code class="inline"><span class="w">unmemoize</span></code>
458
469
 function that you can import if you want to.
459
470
Why would you want to?  Here's an example: Suppose you have your cache
460
471
tied to a DBM file, and you want to make sure that the cache is
462
473
exits normally, this will happen anyway, but if someone types
463
474
control-C or something then the program will terminate immediately
464
475
without synchronizing the database.  So what you can do instead is</p>
465
 
<pre class="verbatim">    <span class="i">$SIG</span>{INT} = <a class="l_k" href="functions/sub.html">sub</a> <span class="s">{</span> unmemoize <span class="q">&#39;function&#39;</span> <span class="s">}</span><span class="sc">;</span></pre>
466
 
<p><code class="inline">unmemoize</code>
 
476
<pre class="verbatim">    <span class="i">$SIG</span>{<span class="w">INT</span>} = <a class="l_k" href="functions/sub.html">sub</a> <span class="s">{</span> <span class="w">unmemoize</span> <span class="q">&#39;function&#39;</span> <span class="s">}</span><span class="sc">;</span></pre>
 
477
<p><code class="inline"><span class="w">unmemoize</span></code>
467
478
 accepts a reference to, or the name of a previously
468
479
memoized function, and undoes whatever it did to provide the memoized
469
480
version in the first place, including making the name refer to the
471
482
unmemoized version of the function.</p>
472
483
<p>If you ask it to unmemoize a function that was never memoized, it
473
484
croaks.</p>
474
 
<a name="'flush_cache'"></a><h2><code class="inline">flush_cache</code>
 
485
<a name="'flush_cache'"></a><h2><code class="inline"><span class="w">flush_cache</span></code>
475
486
</h2>
476
 
<p><code class="inline"><span class="i">flush_cache</span><span class="s">(</span>function<span class="s">)</span></code>
 
487
<p><code class="inline"><span class="i">flush_cache</span><span class="s">(</span><span class="w">function</span><span class="s">)</span></code>
477
488
 will flush out the caches, discarding <i>all</i>
478
489
the cached data.  The argument may be a function name or a reference
479
490
to a function.  For finer control over when data is discarded or
480
 
expired, see the documentation for <code class="inline"><a class="l_w" href="Memoize/Expire.html">Memoize::Expire</a></code>, included in
 
491
expired, see the documentation for <code class="inline"><span class="w">Memoize::Expire</span></code>
 
492
, included in
481
493
this package.</p>
482
 
<p>Note that if the cache is a tied hash, <code class="inline">flush_cache</code>
 
494
<p>Note that if the cache is a tied hash, <code class="inline"><span class="w">flush_cache</span></code>
483
495
 will attempt to
484
 
invoke the <code class="inline">CLEAR</code>
485
 
 method on the hash.  If there is no <code class="inline">CLEAR</code>
 
496
invoke the <code class="inline"><span class="w">CLEAR</span></code>
 
497
 method on the hash.  If there is no <code class="inline"><span class="w">CLEAR</span></code>
486
498
 
487
499
method, this will cause a run-time error.</p>
488
 
<p>An alternative approach to cache flushing is to use the <code class="inline">HASH</code>
 
500
<p>An alternative approach to cache flushing is to use the <code class="inline"><span class="w">HASH</span></code>
489
501
 option
490
 
(see above) to request that <code class="inline"><a class="l_w" href="Memoize.html">Memoize</a></code> use a particular hash variable
 
502
(see above) to request that <code class="inline"><span class="w">Memoize</span></code>
 
503
 use a particular hash variable
491
504
as its cache.  Then you can examine or modify the hash at any time in
492
505
any way you desire.  You may flush the cache by using <code class="inline"><span class="i">%hash</span> = <span class="s">(</span><span class="s">)</span></code>
493
 
. </p>
 
506
.</p>
494
507
<a name="CAVEATS"></a><h1>CAVEATS</h1>
495
508
<p>Memoization is not a cure-all:</p>
496
509
<ul>
502
515
<pre class="verbatim"><a name="f"></a>  sub <span class="m">f</span> <span class="s">{</span>
503
516
          <a class="l_k" href="functions/time.html">time</a><span class="sc">;</span>
504
517
        <span class="s">}</span></pre>
505
 
<p>This function takes no arguments, and as far as <code class="inline"><a class="l_w" href="Memoize.html">Memoize</a></code> is
506
 
concerned, it always returns the same result.  <code class="inline"><a class="l_w" href="Memoize.html">Memoize</a></code> is wrong, of
 
518
<p>This function takes no arguments, and as far as <code class="inline"><span class="w">Memoize</span></code>
 
519
 is
 
520
concerned, it always returns the same result.  <code class="inline"><span class="w">Memoize</span></code>
 
521
 is wrong, of
507
522
course, and the memoized version of this function will call <code class="inline"><a class="l_k" href="functions/time.html">time</a></code> once
508
523
to get the current time, and it will return that same time
509
524
every time you call it after that.</p>
517
532
        <span class="s">}</span></pre>
518
533
<p>This function accepts two arguments, adds them, and prints their sum.
519
534
Its return value is the numuber of characters it printed, but you
520
 
probably didn't care about that.  But <code class="inline"><a class="l_w" href="Memoize.html">Memoize</a></code> doesn't understand
 
535
probably didn't care about that.  But <code class="inline"><span class="w">Memoize</span></code>
 
536
 doesn't understand
521
537
that.  If you memoize this function, you will get the result you
522
538
expect the first time you ask it to print the sum of 2 and 3, but
523
539
subsequent calls will return 1 (the return value of
526
542
<li>
527
543
<p>Do not memoize a function that returns a data structure that is
528
544
modified by its caller.</p>
529
 
<p>Consider these functions:  <code class="inline">getusers</code>
 
545
<p>Consider these functions:  <code class="inline"><span class="w">getusers</span></code>
530
546
 returns a list of users somehow,
531
 
and then <code class="inline">main</code>
 
547
and then <code class="inline"><span class="w">main</span></code>
532
548
 throws away the first user on the list and prints the
533
549
rest:</p>
534
550
<pre class="verbatim"><a name="main"></a>       sub <span class="m">main</span> <span class="s">{</span>
543
559
          <span class="c"># Do something to get a list of users;</span>
544
560
          \<span class="i">@users</span><span class="sc">;</span>  <span class="c"># Return reference to list.</span>
545
561
        <span class="s">}</span></pre>
546
 
<p>If you memoize <code class="inline">getusers</code>
 
562
<p>If you memoize <code class="inline"><span class="w">getusers</span></code>
547
563
 here, it will work right exactly once.  The
548
 
reference to the users list will be stored in the memo table.  <code class="inline">main</code>
 
564
reference to the users list will be stored in the memo table.  <code class="inline"><span class="w">main</span></code>
549
565
 
550
566
will discard the first element from the referenced list.  The next
551
 
time you invoke <code class="inline">main</code>
552
 
, <code class="inline"><a class="l_w" href="Memoize.html">Memoize</a></code> will not call <code class="inline">getusers</code>
 
567
time you invoke <code class="inline"><span class="w">main</span></code>
 
568
, <code class="inline"><span class="w">Memoize</span></code>
 
569
 will not call <code class="inline"><span class="w">getusers</span></code>
553
570
; it will
554
571
just return the same reference to the same list it got last time.  But
555
 
this time the list has already had its head removed; <code class="inline">main</code>
 
572
this time the list has already had its head removed; <code class="inline"><span class="w">main</span></code>
556
573
 will
557
574
erroneously remove another element from it.  The list will get shorter
558
 
and shorter every time you call <code class="inline">main</code>
 
575
and shorter every time you call <code class="inline"><span class="w">main</span></code>
559
576
.</p>
560
577
<p>Similarly, this:</p>
561
578
<pre class="verbatim">  <span class="i">$u1</span> = <span class="i">getusers</span><span class="s">(</span><span class="s">)</span><span class="sc">;</span>    
562
579
        <span class="i">$u2</span> = <span class="i">getusers</span><span class="s">(</span><span class="s">)</span><span class="sc">;</span>    
563
580
        <a class="l_k" href="functions/pop.html">pop</a> <span class="i">@$u1</span><span class="sc">;</span></pre>
564
581
<p>will modify $u2 as well as $u1, because both variables are references
565
 
to the same array.  Had <code class="inline">getusers</code>
 
582
to the same array.  Had <code class="inline"><span class="w">getusers</span></code>
566
583
 not been memoized, $u1 and $u2
567
584
would have referred to different arrays.</p>
568
585
</li>
574
591
<pre class="verbatim"><a name="square"></a>    sub <span class="m">square</span> <span class="s">{</span>
575
592
      <span class="i">$_</span>[<span class="n">0</span>] * <span class="i">$_</span>[<span class="n">0</span>]<span class="sc">;</span>
576
593
    <span class="s">}</span></pre>
577
 
<p>I pointed out that <code class="inline"><a class="l_w" href="Memoize.html">Memoize</a></code> uses a hash, and that looking up a
 
594
<p>I pointed out that <code class="inline"><span class="w">Memoize</span></code>
 
595
 uses a hash, and that looking up a
578
596
number in the hash is necessarily going to take a lot longer than a
579
597
single multiplication.  There really is no way to speed up the
580
 
<code class="inline">square</code>
 
598
<code class="inline"><span class="w">square</span></code>
581
599
 function.</p>
582
600
<p>Memoization is not magical.</p>
583
601
</li>
584
602
</ul>
585
603
<a name="PERSISTENT-CACHE-SUPPORT"></a><h1>PERSISTENT CACHE SUPPORT</h1>
586
604
<p>You can tie the cache tables to any sort of tied hash that you want
587
 
to, as long as it supports <code class="inline">TIEHASH</code>
588
 
, <code class="inline">FETCH</code>
589
 
, <code class="inline">STORE</code>
 
605
to, as long as it supports <code class="inline"><span class="w">TIEHASH</span></code>
 
606
, <code class="inline"><span class="w">FETCH</span></code>
 
607
, <code class="inline"><span class="w">STORE</span></code>
590
608
, and
591
 
<code class="inline">EXISTS</code>
 
609
<code class="inline"><span class="w">EXISTS</span></code>
592
610
.  For example,</p>
593
 
<pre class="verbatim">        <a class="l_k" href="functions/tie.html">tie</a> <a class="l_k" href="functions/my.html">my</a> <span class="i">%cache</span> <span class="cm">=&gt;</span> <span class="q">&#39;GDBM_File&#39;</span><span class="cm">,</span> <span class="i">$filename</span><span class="cm">,</span> O_RDWR|O_CREAT<span class="cm">,</span> <span class="n">0666</span><span class="sc">;</span>
594
 
        memoize <span class="q">&#39;function&#39;</span><span class="cm">,</span> SCALAR_CACHE <span class="cm">=&gt;</span> <span class="s">[</span>HASH <span class="cm">=&gt;</span> \<span class="i">%cache</span><span class="s">]</span><span class="sc">;</span></pre>
 
611
<pre class="verbatim">        <a class="l_k" href="functions/tie.html">tie</a> <a class="l_k" href="functions/my.html">my</a> <span class="i">%cache</span> <span class="cm">=&gt;</span> <span class="q">&#39;GDBM_File&#39;</span><span class="cm">,</span> <span class="i">$filename</span><span class="cm">,</span> <span class="w">O_RDWR</span>|<span class="w">O_CREAT</span><span class="cm">,</span> <span class="n">0666</span><span class="sc">;</span>
 
612
        <span class="w">memoize</span> <span class="q">&#39;function&#39;</span><span class="cm">,</span> <span class="w">SCALAR_CACHE</span> <span class="cm">=&gt;</span> <span class="s">[</span><span class="w">HASH</span> <span class="cm">=&gt;</span> \<span class="i">%cache</span><span class="s">]</span><span class="sc">;</span></pre>
595
613
<p>works just fine.  For some storage methods, you need a little glue.</p>
596
 
<p><code class="inline"><a class="l_w" href="SDBM_File.html">SDBM_File</a></code> doesn't supply an <code class="inline">EXISTS</code>
 
614
<p><code class="inline"><span class="w">SDBM_File</span></code>
 
615
 doesn't supply an <code class="inline"><span class="w">EXISTS</span></code>
597
616
 method, so included in this
598
 
package is a glue module called <code class="inline"><a class="l_w" href="Memoize/SDBM_File.html">Memoize::SDBM_File</a></code> which does
599
 
provide one.  Use this instead of plain <code class="inline"><a class="l_w" href="SDBM_File.html">SDBM_File</a></code> to store your
600
 
cache table on disk in an <code class="inline"><a class="l_w" href="SDBM_File.html">SDBM_File</a></code> database:</p>
601
 
<pre class="verbatim">        <a class="l_k" href="functions/tie.html">tie</a> <a class="l_k" href="functions/my.html">my</a> <span class="i">%cache</span> <span class="cm">=&gt;</span> <span class="q">&#39;Memoize::SDBM_File&#39;</span><span class="cm">,</span> <span class="i">$filename</span><span class="cm">,</span> O_RDWR|O_CREAT<span class="cm">,</span> <span class="n">0666</span><span class="sc">;</span>
602
 
        memoize <span class="q">&#39;function&#39;</span><span class="cm">,</span> SCALAR_CACHE <span class="cm">=&gt;</span> <span class="s">[</span>HASH <span class="cm">=&gt;</span> \<span class="i">%cache</span><span class="s">]</span><span class="sc">;</span></pre>
603
 
<p><code class="inline"><a class="l_w" href="NDBM_File.html">NDBM_File</a></code> has the same problem and the same solution.  (Use
604
 
<code class="inline"><a class="l_w" href="Memoize/NDBM_File.html">Memoize::NDBM_File</a> instead of plain <a class="l_w" href="NDBM_File.html">NDBM_File</a>.</code>
 
617
package is a glue module called <code class="inline"><span class="w">Memoize::SDBM_File</span></code>
 
618
 which does
 
619
provide one.  Use this instead of plain <code class="inline"><span class="w">SDBM_File</span></code>
 
620
 to store your
 
621
cache table on disk in an <code class="inline"><span class="w">SDBM_File</span></code>
 
622
 database:</p>
 
623
<pre class="verbatim">        <a class="l_k" href="functions/tie.html">tie</a> <a class="l_k" href="functions/my.html">my</a> <span class="i">%cache</span> <span class="cm">=&gt;</span> <span class="q">&#39;Memoize::SDBM_File&#39;</span><span class="cm">,</span> <span class="i">$filename</span><span class="cm">,</span> <span class="w">O_RDWR</span>|<span class="w">O_CREAT</span><span class="cm">,</span> <span class="n">0666</span><span class="sc">;</span>
 
624
        <span class="w">memoize</span> <span class="q">&#39;function&#39;</span><span class="cm">,</span> <span class="w">SCALAR_CACHE</span> <span class="cm">=&gt;</span> <span class="s">[</span><span class="w">HASH</span> <span class="cm">=&gt;</span> \<span class="i">%cache</span><span class="s">]</span><span class="sc">;</span></pre>
 
625
<p><code class="inline"><span class="w">NDBM_File</span></code>
 
626
 has the same problem and the same solution.  (Use
 
627
<code class="inline"><span class="w">Memoize::NDBM_File</span> <span class="w">instead</span> <span class="w">of</span> <span class="w">plain</span> <span class="w">NDBM_File</span>.</code>
605
628
)</p>
606
 
<p><code class="inline"><a class="l_w" href="Storable.html">Storable</a></code> isn't a tied hash class at all.  You can use it to store a
 
629
<p><code class="inline"><span class="w">Storable</span></code>
 
630
 isn't a tied hash class at all.  You can use it to store a
607
631
hash to disk and retrieve it again, but you can't modify the hash while
608
632
it's on the disk.  So if you want to store your cache table in a
609
 
<code class="inline"><a class="l_w" href="Storable.html">Storable</a></code> database, use <code class="inline"><a class="l_w" href="Memoize/Storable.html">Memoize::Storable</a></code>, which puts a hashlike
610
 
front-end onto <code class="inline"><a class="l_w" href="Storable.html">Storable</a></code>.  The hash table is actually kept in
611
 
memory, and is loaded from your <code class="inline"><a class="l_w" href="Storable.html">Storable</a></code> file at the time you
 
633
<code class="inline"><span class="w">Storable</span></code>
 
634
 database, use <code class="inline"><span class="w">Memoize::Storable</span></code>
 
635
, which puts a hashlike
 
636
front-end onto <code class="inline"><span class="w">Storable</span></code>
 
637
.  The hash table is actually kept in
 
638
memory, and is loaded from your <code class="inline"><span class="w">Storable</span></code>
 
639
 file at the time you
612
640
memoize the function, and stored back at the time you unmemoize the
613
641
function (or when your program exits):</p>
614
642
<pre class="verbatim">        <a class="l_k" href="functions/tie.html">tie</a> <a class="l_k" href="functions/my.html">my</a> <span class="i">%cache</span> <span class="cm">=&gt;</span> <span class="q">&#39;Memoize::Storable&#39;</span><span class="cm">,</span> <span class="i">$filename</span><span class="sc">;</span>
615
 
        memoize <span class="q">&#39;function&#39;</span><span class="cm">,</span> SCALAR_CACHE <span class="cm">=&gt;</span> <span class="s">[</span>HASH <span class="cm">=&gt;</span> \<span class="i">%cache</span><span class="s">]</span><span class="sc">;</span></pre>
 
643
        <span class="w">memoize</span> <span class="q">&#39;function&#39;</span><span class="cm">,</span> <span class="w">SCALAR_CACHE</span> <span class="cm">=&gt;</span> <span class="s">[</span><span class="w">HASH</span> <span class="cm">=&gt;</span> \<span class="i">%cache</span><span class="s">]</span><span class="sc">;</span></pre>
616
644
<pre class="verbatim">        <a class="l_k" href="functions/tie.html">tie</a> <a class="l_k" href="functions/my.html">my</a> <span class="i">%cache</span> <span class="cm">=&gt;</span> <span class="q">&#39;Memoize::Storable&#39;</span><span class="cm">,</span> <span class="i">$filename</span><span class="cm">,</span> <span class="q">&#39;nstore&#39;</span><span class="sc">;</span>
617
 
        memoize <span class="q">&#39;function&#39;</span><span class="cm">,</span> SCALAR_CACHE <span class="cm">=&gt;</span> <span class="s">[</span>HASH <span class="cm">=&gt;</span> \<span class="i">%cache</span><span class="s">]</span><span class="sc">;</span></pre>
618
 
<p>Include the `nstore' option to have the <code class="inline"><a class="l_w" href="Storable.html">Storable</a></code> database written
 
645
        <span class="w">memoize</span> <span class="q">&#39;function&#39;</span><span class="cm">,</span> <span class="w">SCALAR_CACHE</span> <span class="cm">=&gt;</span> <span class="s">[</span><span class="w">HASH</span> <span class="cm">=&gt;</span> \<span class="i">%cache</span><span class="s">]</span><span class="sc">;</span></pre>
 
646
<p>Include the `nstore' option to have the <code class="inline"><span class="w">Storable</span></code>
 
647
 database written
619
648
in `network order'.  (See <a href="Storable.html">Storable</a> for more details about this.)</p>
620
649
<p>The <code class="inline"><span class="i">flush_cache</span><span class="s">(</span><span class="s">)</span></code>
621
650
 function will raise a run-time error unless the
622
 
tied package provides a <code class="inline">CLEAR</code>
 
651
tied package provides a <code class="inline"><span class="w">CLEAR</span></code>
623
652
 method.</p>
624
653
<a name="EXPIRATION-SUPPORT"></a><h1>EXPIRATION SUPPORT</h1>
625
654
<p>See Memoize::Expire, which is a plug-in module that adds expiration
637
666
in Perl, and until it is resolved, memoized functions will see a
638
667
slightly different <code class="inline"><a class="l_k" href="functions/caller.html">caller()</a></code> and will perform a little more slowly
639
668
on threaded perls than unthreaded perls.</p>
640
 
<p>Some versions of <code class="inline"><a class="l_w" href="DB_File.html">DB_File</a></code> won't let you store data under a key of
641
 
length 0.  That means that if you have a function <code class="inline">f</code>
 
669
<p>Some versions of <code class="inline"><span class="w">DB_File</span></code>
 
670
 won't let you store data under a key of
 
671
length 0.  That means that if you have a function <code class="inline"><span class="w">f</span></code>
642
672
 which you
643
 
memoized and the cache is in a <code class="inline"><a class="l_w" href="DB_File.html">DB_File</a></code> database, then the value of
 
673
memoized and the cache is in a <code class="inline"><span class="w">DB_File</span></code>
 
674
 database, then the value of
644
675
<code class="inline"><span class="i">f</span><span class="s">(</span><span class="s">)</span></code>
645
 
 (<code class="inline">f</code>
 
676
 (<code class="inline"><span class="w">f</span></code>
646
677
 called with no arguments) will not be memoized.  If this
647
678
is a big problem, you can supply a normalizer function that prepends
648
679
<code class="inline"><span class="q">&quot;x&quot;</span></code>
649
680
 to every key.</p>
650
681
<a name="MAILING-LIST"></a><h1>MAILING LIST</h1>
651
682
<p>To join a very low-traffic mailing list for announcements about
652
 
<code class="inline"><a class="l_w" href="Memoize.html">Memoize</a></code>, send an empty note to <code class="inline">mjd-perl-memoize-request<span class="i">@plover</span>.com</code>
 
683
<code class="inline"><span class="w">Memoize</span></code>
 
684
, send an empty note to <code class="inline"><span class="w">mjd</span>-<span class="w">perl</span>-<span class="w">memoize</span>-<span class="w">request</span><span class="i">@plover</span>.<span class="w">com</span></code>
653
685
.</p>
654
686
<a name="AUTHOR"></a><h1>AUTHOR</h1>
655
 
<p>Mark-Jason Dominus (<code class="inline">mjd-perl-memoize+<span class="i">@plover</span>.com</code>
 
687
<p>Mark-Jason Dominus (<code class="inline"><span class="w">mjd</span>-<span class="w">perl</span>-<span class="w">memoize</span>+<span class="i">@plover</span>.<span class="w">com</span></code>
656
688
), Plover Systems co.</p>
657
 
<p>See the <code class="inline"><a class="l_w" href="Memoize.html">Memoize</a>.pm</code>
 
689
<p>See the <code class="inline"><span class="w">Memoize</span>.<span class="w">pm</span></code>
658
690
 Page at <a href="http://www.plover.com/~mjd/perl/Memoize/">http://www.plover.com/~mjd/perl/Memoize/</a>
659
691
for news and upgrades.  Near this page, at
660
692
<a href="http://www.plover.com/~mjd/perl/MiniMemoize/">http://www.plover.com/~mjd/perl/MiniMemoize/</a> there is an article about
666
698
in 2002, possibly under the title <i>Perl Advanced Techniques
667
699
Handbook</i>.  It will also be available on-line for free.  For more
668
700
information, visit <a href="http://perl.plover.com/book/">http://perl.plover.com/book/</a> .</p>
669
 
<p>To join a mailing list for announcements about <code class="inline"><a class="l_w" href="Memoize.html">Memoize</a></code>, send an
670
 
empty message to <code class="inline">mjd-perl-memoize-request<span class="i">@plover</span>.com</code>
 
701
<p>To join a mailing list for announcements about <code class="inline"><span class="w">Memoize</span></code>
 
702
, send an
 
703
empty message to <code class="inline"><span class="w">mjd</span>-<span class="w">perl</span>-<span class="w">memoize</span>-<span class="w">request</span><span class="i">@plover</span>.<span class="w">com</span></code>
671
704
.  This mailing
672
705
list is for announcements only and has extremely low traffic---about
673
706
two messages per year.</p>
690
723
helpful suggestions, to Jonathan Roy (again) for finding a use for
691
724
<code class="inline"><span class="i">unmemoize</span><span class="s">(</span><span class="s">)</span></code>
692
725
, to Philippe Verdret for enlightening discussion of
693
 
<code class="inline">Hook::PrePostCall</code>
 
726
<code class="inline"><span class="w">Hook::PrePostCall</span></code>
694
727
, to Nat Torkington for advice I ignored, to Chris
695
728
Nandor for portability advice, to Randal Schwartz for suggesting the
696
 
'<code class="inline">flush_cache</code>
 
729
'<code class="inline"><span class="w">flush_cache</span></code>
697
730
 function, and to Jenda Krynicky for being a light in
698
731
the world.</p>
699
732
<p>Special thanks to Jarkko Hietaniemi, the 5.8.0 pumpking, for including
716
749
          <!--<select name="r"><option value="1" selected>Go to top result<option value="0">Show results list</select>-->
717
750
        </form>
718
751
      </p>
 
752
      <script language="JavaScript" type="text/javascript" src="/perl-version.js"></script>
719
753
      <h2>Labels:</h2>
720
754
      <p>
721
755
        <a href="#" onClick="addLabel('Memoize','Memoize.html')">Add this page</a>