gensym vs. other way

A

Alex Hart

I thought that these are equivalent:

use Symbol;
my $fh = gensym;

and

local *FH;
my $fh = \*FH;

But the following code doesn't treat them the same.

#!/usr/bin/perl -w

use Symbol;
use strict;

my $file = Test_close->new("test");

package Test_close;
{
my $testdiename;
sub new {
my ($class, $name) = @_;
print ("Test_close on $name\n");
$testdiename=$name;
local *TMP;
my $tmp = \*TMP; # THIS LINE AND THE NEXT ARE THE TEST
# my $tmp = Symbol::gensym();
bless $tmp, $class;
}

sub DESTROY {
print "\n\n$testdiename died\n\n";
}
}
__END__


When I run this using gensym, it does what I expect, but when I create
the anonymous glob myself, the DESTROY function is not called.

Can someone explain what's the difference and why the object is not
destroyed.

Thanks.

- Alex Hart
 
B

Brian McCauley

Alex said:
I thought that these are equivalent:

use Symbol;
my $fh = gensym;

and

local *FH;
my $fh = \*FH;

Well, fairly close.

GLOBs and local() are scary things.

GLOBs are little structures that contain a SCALAR ref, and ARRAY ref, a
HASH ref, a CODE ref, an IO ref and so on.

What local does is change GLOB it does does _not_ create a new GLOB
structure and change the symbol table to point to that one.

open(FH,'>','/dev/null') or die $!;
print \*FH,*FH{IO},"\n"; # GLOB(0x18243e8)IO::Handle=IO(0x1824418)
local *FH;
print \*FH,*FH{IO},"\n"; # GLOB(0x18243e8)

So you are not actually creating an anonymous GLOB. If you bless *FH
then the destructor is not called because *FH itself is not destryed
when you hit the end of the local scope.

Now, Perl's scalar variables are able to hold GLOB stuctures so you can say

my $fh = do { local *FH };

This temporarily clears all the entries in the GLOB *FH and then places
a duplicate of that GLOB structure in $fh.

Note that here the scalar variable $fh _becomes_ and anonymous GLOB. It
is IMNSHO better to avoid fiddling with these naked anonymous GLOBs.

I prefer to work with GLOBrefs which feel much cleaner.

my $fh = do { my $glob = local *FH; \$glob };

This is more or less what Symbol::gensym does.

If you bless $fh now you are blessing the duplicate GLOB object, the one
that will be garbage collected when the reference to it in $fh goes away.

Anyhow all this is largely moot in current Perl as it's much simpler to
use autovivification to get anonymous GLOB refs.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top