Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Re^3: Looking for suitable spells to get open to return a filehandle from a module

by AnomalousMonk (Archbishop)
on Nov 28, 2016 at 07:02 UTC ( [id://1176685]=note: print w/replies, xml ) Need Help??


in reply to Re^2: Looking for suitable spells to get open to return a filehandle from a module
in thread SOLVED: Looking for suitable spells to get open to return a filehandle from a module

What is the effect of the invocation of Symbol::gensym? This code seems to work just fine without it both with aliasing and with an automatic reference via a prototype (also minimally tested):
t_extra_open.pl:

use warnings; use strict; use Extra; { my $filename = 'extra-open.txt'; Extra::open my $fh, '>', $filename or die "opening '$filename' for write: $!"; defined $fh or die "write filehandle not defined"; print $fh "Extra open works just fine \n"; print $fh "at ", scalar(localtime), "\n"; close $fh or die "closing '$filename' after write"; undef $fh; Extra::open $fh, '<', $filename or die "opening '$filename' for read: $!"; defined $fh or die "read filehandle not defined"; print '<<', <$fh>, '>>'; close $fh or die "closing '$filename' after read"; }
Extra.pm:
package Extra; sub open { # works my (undef, $direction, $filename) = @_; return open $_[0], $direction, $filename; } # sub open (\$@) { # works # # my ($sr_fh, $direction, $filename) = @_; # # return open $$sr_fh, $direction, $filename; # # } 1;
(Tested under ActiveState 5.8.9 and Strawberry 5.14.4.1.)


Give a man a fish:  <%-{-{-{-<

Replies are listed 'Best First'.
Re^4: Looking for suitable spells to get open to return a filehandle from a module
by afoken (Chancellor) on Dec 03, 2016 at 16:58 UTC
    What is the effect of the invocation of Symbol::gensym?

    In this case, just a lazily copied expression. Quoting Symbol:

    Symbol::gensym creates an anonymous glob and returns a reference to it. Such a glob reference can be used as a file or directory handle.

    And that's it. It was needed in ancient perls. Perl 5.6.1 introduced autovivication for file and directory handles (see perl561delta), so Symbol::gensym is technically no longer needed. open my $fh, ... or open local $fh, ... is sufficient.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
      ... so Symbol::gensym is technically no longer needed

      But there are times when it's still useful... like when you want open3() to keep STDOUT and STDERR separate (by default, if you pass it undef for both STDOUT and STDERR, STDERR will be directed to the same filehandle that's created for STDOUT)

      #!/usr/bin/env perl use warnings; use strict; use IPC::Open3; use Symbol qw(gensym); use POSIX qw(:sys_wait_h); # I'm sometimes using perl 5.8.5, so //'<undef>' unavailable # verified later on 5.14.2 sub defor($) { defined($_[0]) ? $_[0] : '<undef>' } foreach my $run (1..3) { my ($out, $err) = ('',''); my ($fhi, $fho, $fhe) = ($run == 1) ? (undef, undef, undef) : # when fhe==un +def goes to open3, STDERR will be redirected to STDOUT ($run == 2) ? (undef, undef, gensym) : # this keeps S +TDERR and STDOUT separate (gensym, gensym, gensym) ; # as does this +, the first two gensym are unecessary, but the third is needed my $pid = open3( $fhi, $fho, $fhe, qq[cat - ; perl -le 'print STDE +RR "this should be STDERR (run#$run)...\nand so should this (run#$run +)\n"'] ); print { $fhi } "[run#$run] This should be STDOUT\n"; close($fhi); $out .= join '', map { s/^/STDOUT> / if $_ ne $/; $_ } readline($f +ho) if defined $fho; $err .= join '', map { s/^/STDOUT> / if $_ ne $/; $_ } readline($f +he) if defined $fhe; print "Read STDOUT:\n$out\n" if length($out); print "Read STDERR:\n$err\n" if length($err); printf "run#%d --- fhi='%s' fho='%s' fhe='%s'\n", $run, defor $fhi +, defor $fho, defor $fhe; print "="x75, "\n\n"; } __END__ Read STDOUT: STDOUT> [run#1] This should be STDOUT STDOUT> this should be STDERR (run#1)... STDOUT> and so should this (run#1) run#1 --- fhi='GLOB(0x92fdba4)' fho='GLOB(0x92fdbcc)' fhe='<undef>' ====================================================================== +===== Read STDOUT: STDOUT> [run#2] This should be STDOUT Read STDERR: STDOUT> this should be STDERR (run#2)... STDOUT> and so should this (run#2) run#2 --- fhi='GLOB(0x93811c0)' fho='GLOB(0x932bc60)' fhe='GLOB(0x92fd +ba4)' ====================================================================== +===== Read STDOUT: STDOUT> [run#3] This should be STDOUT Read STDERR: STDOUT> this should be STDERR (run#3)... STDOUT> and so should this (run#3) run#3 --- fhi='GLOB(0x93811c0)' fho='GLOB(0x932bc60)' fhe='GLOB(0x92fd +ba4)' ====================================================================== +=====

      Yes, I know the OP didn't include open3, but since I was recently learning the ins and outs of open3 filehandles, I thought I'd mention this exception to your general rule, for posterity's sake.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1176685]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (7)
As of 2024-04-23 19:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found