Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
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 goofing around in the Monastery: (8)
As of 2024-04-24 09:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found