gensym vs. other way

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

Threaded View
I thought that these are equivalent:

use Symbol;
my $fh = gensym;


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");
local *TMP;
#    my $tmp = Symbol::gensym();
bless $tmp, $class;

print "\n\n$testdiename died\n\n";

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


- Alex Hart

Re: gensym vs. other way

Alex Hart wrote:

> 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,"\n"; # GLOB(0x18243e8)IO::Handle=IO(0x1824418)
local *FH;
print \*FH,*FH,"\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.

Re: gensym vs. other way

Very helpful. Thanks a lot.

Site Timeline