Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Re: Filehandle in subroutine in use VRML.pm

by BillKSmith (Monsignor)
on Jul 07, 2022 at 21:51 UTC ( [id://11145348]=note: print w/replies, xml ) Need Help??


in reply to Filehandle in subroutine in use VRML.pm

The documentation for open states:
If FILEHANDLE is an undefined scalar variable (or array or hash element), a new filehandle is autovivified, meaning that the variable is assigned a reference to a newly allocated anonymous filehandle. Otherwise if FILEHANDLE is an expression, its value is the real filehandle. (This is considered a symbolic reference, so use strict "refs" should not be in effect.)

You initialize $fh with LF. Under strict, all three options produce the expected error:

Can't use string ("LF") as a symbol ref while "strict refs" in use ...
The real question is why do options 0 and 1 appear to work as intended without strict. I have no idea.

The minimal (not recommended) 'fix' is to remove LF from the call to mystart. This leaves $fh uninitalized.

#&mystart($LumberFile,LF); &mystart($LumberFile);
Bill

Replies are listed 'Best First'.
Re^2: Filehandle in subroutine in use VRML.pm
by smittypaddler (Acolyte) on Jul 17, 2022 at 21:06 UTC

    None of the suggestions have worked, but I found a solution. In my VRML.pm file, in any subroutine printing output, I added a myprint argument and where the subroutine originally invoked &printout, I changed it to invoke \&myprint, where @lines is an array of lines to be printed:

    sub egg { # prints a 3d egg. my %args=(myprint => \&printout, xaxis => 10, ...); # Produces lines of wrl output in @lines ... $myprint=$args{myprint}; &{$myprint}(\@lines); }

    In DrillPressTable.pl, which uses VRML.pm, I added a global $Fh, and changed the invocation of mystart, and its code, and myprint's code as well:

    my $Fh; # w/b set in mystart. &mystart($LumberFile,LF); sub mystart { my($file,$fh)=@_; open($fh,"> $file") || die("ERROR: Unable to open $file for output"); $Fh=$fh; my @lines=split(/\n/,<<END); #VRML V2.0 utf8 NavigationInfo { headlight TRUE } ... END &myprint(\@lines); } sub myprint { my($lines)=@_; foreach my $line (@{$lines}) { print $Fh "$line\n"; } }

    So now in DrillPressTable.pl I can direct lines of output to multiple file handles, and I don't need to change any of the 70-odd perl programs that use my VRML.pm. They'll just take the default of &printout, which prints to STDOUT, just like before.

      None of the suggestions have worked

      All five (!) of the variations of solutions I posted in this thread work correctly when applied to the sample code you posted. This means that either you did not apply the suggestions correctly, or that your sample code was not representative of your actual code. In either case, see Short, Self-Contained, Correct Example and I know what I mean. Why don't you?

      I am pleased to hear that you solved your problem yourself. Are you aware that this new solution is still not compliant with strict refs? You have already demonstrated the problem with this. Minor changes can break your code in ways that are very hard to debug. Not a good idea for a widely used module! At the very least, I would recommend that you specify use strict for the whole program. Specify no strict refs in the smallest possible scope.

      It now sounds like your real problem is how to change the default output of your module. Look at the library function select. It may do exactly what you want.

      Bill

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (2)
As of 2024-04-19 18:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found