<?xml version="1.0" encoding="windows-1252"?>
<node id="138636" title="Oh my God! Tie killed Perl!" created="2002-01-14 17:09:08" updated="2005-08-14 15:29:35">
<type id="120">
perlmeditation</type>
<author id="3607">
Petruchio</author>
<data>
<field name="doctext">
&lt;p&gt;
 &lt;i&gt;(scroll to the bottom for the code)&lt;/i&gt;
&lt;/p&gt;
&lt;p&gt;
 &lt;i&gt;Cafeteria.  Enter Chef, boys.&lt;/i&gt;
&lt;/p&gt;
&lt;p&gt;
 Chef: Hello there, children! 
&lt;/p&gt;
&lt;p&gt;
 The boys: Hey, Chef. 
&lt;/p&gt;
&lt;p&gt;
 Chef: How's it goin'? 
&lt;/p&gt;
&lt;p&gt;
 The boys: Bad. 
&lt;/p&gt;
&lt;p&gt;
 Chef: Why bad? 
&lt;/p&gt;
&lt;p&gt;
 [Petruchio]: My Perl script won't run right.
&lt;/p&gt;
&lt;p&gt;
 Chef: Oh, that's too bad.  What's wrong with it?
&lt;/p&gt;
&lt;p&gt;
 Perl: Mrgmrmph.
&lt;/p&gt;
&lt;p&gt;
 [Petruchio]:  I think it's that stupid [tie].
&lt;/p&gt;
&lt;p&gt;
 Chef: Woah, hold on there, [Petruchio]!  [tye]'s a 
 very good coder, I'm sure he wouldn't...
&lt;/p&gt;
&lt;p&gt;
 [Petruchio]: Dude, not &lt;i&gt;that&lt;/i&gt; [tye]!  You know, 
 the [tie] that lets you disguise your own object as
 an ordinary Perl variable, so you can use the nice
 syntax.
&lt;/p&gt;
&lt;p&gt;
 Perl: Mremrmrm
&lt;/p&gt;
&lt;p&gt;
 Chef: Oh, I see. Well, you know, children, when I'm
 fixing one of my recipes, I like to reduce it to
 a minimal test case.  I replace as many variables as
 possible with literals, remove subroutines so the
 test is short and linear, and so on. I keep taking
 things away, but I keep the bug there. Then I can
 usually see what I've done wrong.
&lt;/p&gt;
&lt;p&gt;
 Perl: Mwramergmph.
&lt;/p&gt;
&lt;p&gt;
 [Petruchio]: Oh, you mean like:
&lt;/p&gt;
&lt;code&gt;perl -e 'package X;sub TIEHASH{bless{},shift};tie my %x,"X";sub DESTROY{untie %x}'
&lt;/code&gt;
&lt;p&gt;
 &lt;i&gt;Segementation Fault&lt;/i&gt;
&lt;/p&gt;
&lt;READMORE&gt;
&lt;p&gt;
 [Arguile]: What the...?
&lt;/p&gt;
&lt;p&gt;
 [Petruchio]: Oh my God!  Tie killed Perl!
&lt;/p&gt;
&lt;p&gt;
 [OeufMayo]: Bastard!
&lt;/p&gt;
&lt;p&gt;
 Chef:  My, my.  That's not your bug, [Petruchio].  Perl
 shouldn't do that, even though your example is pretty 
 strange.  But what are you running?  I'm using 
 Perl 5.6.0 on DEC/Alpha, and it's not segfaulting for 
 me.
&lt;/p&gt;
&lt;p&gt;
 [Petruchio]: I'm running 5.6.1 on Debian Linux.  Hey!
 it's not segfaulting if I use Perl 5.005_03 on Debian
 or FreeBSD. But when I SSH to a Redhat box and run
 it with 5.6.0, it segfaults &lt;i&gt;and&lt;/i&gt; dumps core.
&lt;/p&gt;
&lt;p&gt;
 [OeufMayo]: Dude, Win32 5.6.1 segfaults too!
&lt;/p&gt;
&lt;p&gt;
 [Arguile]: Shall I try on 5.6.1 for FreeBSD, and 
 the shame version for OSX?  Schweet!  A shegfault
 on FreeBSD, and a bus error on MacOSX. But I'm on
 that over an SSH connection so it might be shegfault
 as well.
&lt;/p&gt;
&lt;p&gt;
 Chef: But [Petruchio], what were you trying to do, 
 anyway? You know the DESTROY sub only gets called
 after the UNTIE sub, so why are you calling untie
 there?
&lt;/p&gt;
&lt;p&gt;
 [Petruchio]: Oh, I know, Chef. I was getting strange
 errors and unexpected exits because I was storing 
 a reference to the variable being tied in a lexical
 array. You know, a flyweight object. The variable's
 original value seems to disappear when you tie it,
 and reappear again when you untie it.  It's a lot
 like [local].  In fact, I suspect it uses the same
 mechanism somehow.
&lt;/p&gt;
&lt;p&gt;
 Chef: I see.  But...
&lt;/p&gt;
&lt;p&gt;
 [Petruchio]: Anyway, I wanted the tied variable to
 keep the values it had just before it was untied.
 So I kept a reference to it in the lexical array,
 and then tried to reset the value during the
 DESTROY block, once the underlying variable had
 been uncovered.
&lt;/p&gt;
&lt;p&gt;
 Chef: I see. But don't you think...
&lt;/p&gt;
&lt;p&gt;
 [Petruchio]: And really weird stuff happens when you 
 you start tying the different elements in a tied hash
 or array... and then if you alias typeglobs to them...
&lt;/p&gt;
&lt;p&gt;
 [Arguile]: Dude, your schript sucks.
&lt;/p&gt;
&lt;p&gt;
 [Petruchio]: Shut up, [Arguile]!
&lt;/p&gt;
&lt;p&gt;
 Chef: Well... [Petruchio]... didn't [tilly|Mr. Tilly]
 tell you not to go abusing tie like that?  
&lt;/p&gt;
&lt;p&gt;
 [Petruchio]: Yeah, I know. They're all really objects 
 anyway, and by pushing tie too far I'm making the code
 more complex and error-prone.  Tie should make things
 easier. But it was interesting, and now I understand
 tie better.
&lt;/p&gt;
&lt;p&gt;
 Chef: Oh, I understand.  I like a little syntactic 
 sugar myself, heh, heh.  &lt;i&gt;Expressing love so sweet... 
 baby, you know I want to... taste that sugar...&lt;/i&gt;
&lt;/p&gt;
&lt;p&gt;
 [Petruchio]: Chef?
&lt;/p&gt;
&lt;p&gt;
 Chef: Oh, uh... yeah, [Petruchio]?
&lt;/p&gt;
&lt;p&gt;
 [Petruchio]: Here's the important part of my code:
&lt;/p&gt;
&lt;code&gt;
#!/usr/bin/perl

package Eraseme;

use strict;
use Data::Dumper;

my @object;

tie my %x, 'Eraseme';
print "Outside:\n";
print Dumper( \@object );

#print keys %{ $object[0][0] }; print "Uncommenting this won't prevent it.\n";
#print Dumper( $object[0][0] ); print "Uncommenting this won't either.\n";

#untie %x; print "Uncommenting this, however, prevents the error.\n";

sub TIEHASH {
  push @object, [ \%x ];
  my $ret = bless { }, 'Eraseme';
  print "Inside:\n";
  print Dumper( \@object );
  $ret;
}

sub DESTROY  { 
#  print Dumper( $object[0][0] ); print "Uncomment this. See? It exited.\n";
#  untie %x;                      print "Uncomment this, and Segfault!.\n";
  print keys %{ $object[0][0] }; 
  print "Destroyed\n";
}

sub FIRSTKEY { }
sub STORE    { }
sub FETCH    { }
sub NEXTKEY  { }
sub EXISTS   { }
sub DELETE   { }
sub CLEAR    { }
&lt;/code&gt;
&lt;p&gt;
 Chef: Well, isn't that something?  Says, &lt;i&gt;(in 
 cleanup) Can't call method "FIRSTKEY" on an undefined
 value at ./Eraseme.pl line 31 during global
 destruction.&lt;/i&gt;
&lt;/p&gt;
&lt;p&gt;
 [Petruchio]: Yeah! Only the one-liner didn't segfault
 for you, so it can't be the same bug, can it?
&lt;/p&gt;
&lt;p&gt;
 Chef: I don't know, [Petruchio].  It could still be
 your bug. you know.  Why don't you ask your little 
 PerlMonk friends to look at it?  Some of them might
 have some interesting things to say about it.
&lt;/p&gt;
&lt;p&gt;
 [Petruchio]: Yeah!  I'll write it up!  Thanks, Chef.
&lt;/p&gt;
&lt;p&gt;
 [Arguile]: Come on.  I want some Cheesy Poofs.
&lt;/p&gt;
&lt;p&gt;
 &lt;i&gt;Exeunt boys&lt;/i&gt;
&lt;/p&gt;
&lt;p&gt;
 Chef: My, my, they do get themselves into trouble. 
 Oh my gosh!  It's almost noon - I'll be late for the
 award ceremony! &lt;i&gt;hmm hmm hmm... You know... Kathy 
 Lee... you are a very special woman...&lt;/i&gt;
&lt;/p&gt;
&lt;p&gt;
 &lt;i&gt;Exit Chef&lt;/i&gt;
&lt;/p&gt;
&lt;p&gt;
 &lt;small&gt;&lt;b&gt;Update&lt;/b&gt; - many thanks to [tye] for
 educating me on the proper use of the word 'exeunt'.
 It means, 'they go out', and is used particularly 
 when speaking in the plural. The boys &lt;i&gt;exeunt&lt;/i&gt;,
 the Chef &lt;i&gt;exits&lt;/i&gt;.&lt;/small&gt;
&lt;/p&gt;</field>
</data>
</node>
