http://qs1969.pair.com?node_id=11145313


in reply to Filehandle in subroutine in use VRML.pm

Thank you for providing enough code to reproduce your issue!

The problem is that because you're not using strict "refs" (Update: and strict "subs"), there is some funky symbolic reference stuff going on here. It's unclear to me why you even need to pass the parameter LF in &mystart($LumberFile,LF);, but AFAICT what is going on here is that that call is actually being interpreted as &mystart($LumberFile,"LF");, and then inside VRML.pm there is no filehandle named LF because that was opened in the main package.

The best thing to do is to rewrite your code so that it works under strict and warnings. The minimum changes I would recommend is to change the definition and call of mystart as follows:

mystart($LumberFile); sub mystart { my ($file) = @_; open( my $fh, "> $file" ) or die ...

If you need the $fh parameter to mystart, you need to show us more context as to how it gets used for us to make a recommendation for a useful replacement (Update: Re^3: Filehandle in subroutine in use VRML.pm).

However, I see several other older code styles in your sample code, for example using the -w shebang switch (What's wrong with -w and $^W), using the old ampersand-style sub calls (perlsub), and the two-argument open ("open" Best Practices). So here's your sample code updated to modern Perl, I strongly suggest you adopt this style for all your code:

#!/usr/bin/perl use warnings; use strict; use VRML; my $Dir = "vrmlstuff"; my $Subdir = "DrillPressTable"; my $LumberFile = "$Dir/$Subdir/lumber.wrl"; mystart($LumberFile); sub mystart { my ($file) = @_; open my $fh, '>', $file or die "ERROR: Unable to open $file for output"; my @lines = split /\n/, <<END; #VRML V2.0 utf8 NavigationInfo { headlight TRUE } DirectionalLight { # First child direction 0 0 -1 # Light illuminating the scene } END my $i = 0; if ( $i == 0 ) { for my $line (@lines) { print $fh "$line\n"; } } elsif ( $i == 1 ) { myprint( \@lines, $fh ); } elsif ( $i == 2 ) { printout( \@lines, $fh ); } } sub myprint { my ($lines, $fh) = @_; for my $line ( @{$lines} ) { print $fh "$line\n"; } }

VRML.pm:

#!/usr/bin/perl package VRML; use warnings; use strict; use Exporter 'import'; our @EXPORT = qw/printout/; sub printout { my ($lines, $fh) = @_; $fh = *STDOUT unless $fh; for my $line ( @{$lines} ) { print $fh "$line\n"; } } 1;