Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

dumping lexical filehandles (updated)

by LanX (Saint)
on Sep 12, 2014 at 15:11 UTC ( [id://1100409]=perlquestion: print w/replies, xml ) Need Help??

LanX has asked for the wisdom of the Perl Monks concerning the following question:

Brothers!

I'm trying to understand how lexical filehandles are dumped:

> perl use Data::Dumper qw/Dumper/; use Data::Dump; open my $fh,"<",'/tmp/tst'; dd $fh; dd $::{'$fh'}; print Dumper $fh; __END__ \*main::$fh undef $VAR1 = \*{'::$fh'};

apparently $fh holds the ref to a glob named "\$fh" , i.e. with sigle as part of the name!

But inspecting the STASH doesn't show this entry...

I know that the common way to copy a bare filehandle to a scalar is my $fh=\*FH but this is confusing me.

Is this an implementation workaround or what am I missing?

edit

Just after posting I'm realizing that I may be inspecting the wrong ($ = scalar) slot of the $fh glob. I'll update further tests.

update

OK inspecting only the glob reveals it's existence in the stash:

dd *{'::$fh'}; # => *main::$fh

but I'm still a bit confused ...

So lexical file handles are implemented as hidden global stash entries, which are destroyed when the lexical var falls out of scope ?

Cheers Rolf

(addicted to the Perl Programming Language and ☆☆☆☆ :)

Replies are listed 'Best First'.
Re: dumping lexical filehandles (not in STASH)
by tye (Sage) on Sep 12, 2014 at 17:26 UTC
    OK inspecting only the glob reveals it's existence in the stash:

    No, I don't think so. open my $fh creates a GLOB that is not in any STASH and stores a reference to it in $fh. It also places a name in that STAB in case somebody dumps it. You can achieve similar end results using the old technique of pure Perl:

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

    But I really doubt that 'open my $fh' goes to such lengths. It just creates a disembodied GLOB w/ a name filled in.

    #!/usr/bin/perl -l print 'before: ', join ' ', keys %foo::; my $fh; { package foo; open $fh, '<-' or die $!; } print 'after opened $fh: ', join ' ', keys %foo::; *{ 'foo::$bar' } = \'bar'; print 'created *$bar: ', join ' ', keys %foo::; print 'foo::$bar = ', ${'foo::$bar'}; { package foo; our $bar; open $bar, '<-' or die $!; print 'foo::$bar = ', ${'foo::$bar'}; print 'foo::bar = ', ${'foo::bar'}; print 'after $bar: ', join ' ', keys %foo::; } eval q{ package foo; local *baz = \'baz'; }; print 'after local *baz: ', join ' ', keys %foo::; __END__ before: bar after opened $fh: bar created *$bar: bar $bar foo::$bar = bar foo::$bar = bar foo::bar = GLOB(0x4f824c) after $bar: bar $bar after local *baz: bar baz $bar

    - tye        

      you're right and I think I isolated the problem...

      Neither Data::Dumper nor Data::Dump are buggy, it's Perl who stores the current package-name into a slot *$fh{PACKAGE} of the globref in $fh

      > perl package BLA; $\="\n"; open my $fh,">",'/tmp/tst'; print "globname: ", *$fh{NAME}; print "globpkg: " , *$fh{PACKAGE}; print 'Stashkey $BLA::{$fh} found? ', scalar grep {/\$fh/} keys %BLA:: +; __END__ globname: $fh globpkg: BLA Stashkey $BLA::{$fh} found? 0

      *$fh{PACKAGE} should be empty or undef or hold a magic dummy

      Cheers Rolf

      (addicted to the Perl Programming Language and ☆☆☆☆ :)

Re: dumping lexical filehandles (solved)
by LanX (Saint) on Sep 12, 2014 at 15:32 UTC
    > So lexical file handles are implemented as hidden global stash entries, which are destroyed when the lexical var falls out of scope ?

    fascinating, seems like scoping behavior is implemented by localizing the hidden stash entry :)

    #!perl use Data::Dumper qw/Dumper/; open my $fh,"<",'/tmp/tst'; my $outer=$fh; print 0+($outer == $fh),": ", Dumper $fh; { open my $fh,"<",'/tmp/tst'; print 0+($outer == $fh),": ", Dumper $fh; }

    out

    1: $VAR1 = \*{'::$fh'}; 0: $VAR1 = \*{'::$fh'};

    Cheers Rolf

    (addicted to the Perl Programming Language and ☆☆☆☆ :)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1100409]
Front-paged by Athanasius
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (4)
As of 2024-04-19 03:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found