<?xml version="1.0" encoding="windows-1252"?>
<node id="642489" title="papidave's scratchpad" created="2007-10-03 15:53:40" updated="2007-10-03 11:53:40">
<type id="182711">
scratchpad</type>
<author id="584007">
papidave</author>
<data>
<field name="doctext">
I've been banging my head on the table with Apache::Session::MySQL today.  Consider:&lt;p&gt;

&lt;code&gt;
eval {
   ( my %session, $ok );
   $ok = tie( %session, 'Apache::Session::MySQL', undef, ... );
   if ( $ok )
   {
      ... do something with %session ...
   }
   untie %session;
}
&lt;/code&gt;

This doesn't work from mod_perl, because the untie throws an exception:  

&lt;blockquote&gt;
&lt;tt&gt;
untie attempted while 1 inner references still exist at foo.pl line 250.
&lt;/tt&gt;
&lt;/blockquote&gt;

Since I don't use any explicit references to &lt;tt&gt;%session&lt;/tt&gt;, this caught me by surprise.  Can you see the bug?  
&lt;p&gt;
&lt;spoiler&gt;
The trick here is to read the fine print on the return code provided by &lt;tt&gt;tie&lt;/tt&gt;:  

&lt;blockquote&gt;
The object returned by the constructor is in turn returned by the &lt;tt&gt;tie&lt;/tt&gt; function, which can be useful if you want to access other methods in CLASSNAME
&lt;/blockquote&gt;

In other words, I can't &lt;tt&gt;untie %session&lt;/tt&gt; because &lt;tt&gt;$ok&lt;/tt&gt; is still holding a reference to it.  One fix is to assign &lt;tt&gt;$ok&lt;/tt&gt; &lt;i&gt;to a constant&lt;/i&gt; if and only if tie returns a non-false value, e.g.:  

&lt;code&gt;
eval {
   ( my %session, $ok );
   tie( %session, 'Apache::Session::MySQL', undef, ... )
         and $ok = 1;
   if ( $ok )
   {
      ... do something with %session ...
   }
   untie %session;
}
&lt;/code&gt;

This eliminates the duplicate reference to %session, so my session properly goes away.  Thank you each for the alternate solutions suggested by monks in the CB:

&lt;ul&gt;
&lt;li&gt;&lt;c&gt;if ( tie( ... ) ) { $ok = 1 }&lt;/c&gt;&lt;/li&gt;
&lt;li&gt;&lt;c&gt;$ok = tie( ... ) &amp;&amp; 1;&lt;/c&gt;&lt;/li&gt;
and one particularly elegant answer, from [tye]:
&lt;li&gt;&lt;c&gt;$ok = !! tie( ... );&lt;/c&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;/spoiler&gt;
</field>
</data>
</node>
