Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

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

by Athanasius (Archbishop)
on Nov 28, 2016 at 04:37 UTC ( [id://1176675]=note: print w/replies, xml ) Need Help??


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

Hello talexb,

You are passing in $fh as a scalar, then overwriting it in the line $fh = Symbol::gensym;, so $fh works correctly inside Extra::open but remains undef in the caller. You need to pass in a reference, and dereference it accordingly within Extra::open:

{ my $fh; Extra::open ( \$fh, '>', 'extra-open.txt' ) or die "2. Open failed: $!"; defined $fh or die "2. Filehandle not defined"; print $fh "Extra open works fine.\n"; close ( $fh ); }
package Extra; use Symbol; sub open { my ( $fh, $direction, $filename ) = @_; $$fh = Symbol::gensym; open ( $$fh, $direction, $filename ); } 1;

In my (minimal) testing, this writes the correct messages to the two output files, and no error is generated.

Hope that helps,

Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Replies are listed 'Best First'.
Re^2: Looking for suitable spells to get open to return a filehandle from a module
by afoken (Chancellor) on Nov 28, 2016 at 06:17 UTC
    package Extra; use Symbol; sub open { my ( $fh, $direction, $filename ) = @_; $$fh = Symbol::gensym; open ( $$fh, $direction, $filename ); } 1;

    I think this should work without explicit references:

    sub open { my (undef, $direction, $filename)=@_; $_[0]=Symbol::gensym; open ($_[0],$direction,$filename); }

    The trick is not to copy the alias in @_, but to directly use the alias. Maybe you need to extend open to have a prototype of ($$$).

    Anyway, I would prefer a modified open function to return a handle or undef instead of a boolean, so:

    sub open { my ($direction,$filename)=@_; open my $h,$direction,$filename or return; # alternatively: or die "Can't open $filename: $!"; return $h; }

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

      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:  <%-{-{-{-<

        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". ;-)
      I would prefer a modified open function to return a handle
      I agree that creating the filehandle within the sub and returning it to the caller is by far the simplest and the best solution (unless I miss something from the OP requirement).
Re^2: Looking for suitable spells to get open to return a filehandle from a module
by talexb (Chancellor) on Nov 28, 2016 at 13:34 UTC

    Brilliant. Thanks!

    Alex / talexb / Toronto

    Thanks PJ. We owe you so much. Groklaw -- RIP -- 2003 to 2013.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (3)
As of 2025-07-18 07:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.