Problem using print with a reference to a filehandle

  • Thread starter niall.macpherson
  • Start date
N

niall.macpherson

I have a sub routine which is passed a reference to a scalar. It opens
a file for writing and sets the scalar passed to the value of the
filehandle produced by the open.

I then print to the file from the calling function. This works as
expected

print $newfh 'somestring ' , $strs[0], ' another ' , $strs[1], "\n";

I assumed I should be able to use the same syntax to print to the file
within the subroutine , although of course I need to dereference the
filehandle using $$. However this gave me an error

String found where operator expected at
C:\develop\NiallPerlScripts\printtest1.p
l line 18, near "$r_newfh 'in function line 1 '"
(Missing operator before 'in function line 1 '?)

The print only succeeds if I enclose all the arguments in parentheses.
The parentheses are not required in the calling function

Sorry if this is not crystal clear - Here is a complete program which
demonstrates the problem

----------------------------------------------------------------------------------------------------------------------
use strict;
use warnings;

##------------------------------------------------
sub OpenAndPrint
{

my ($r_newfh, $text) = @_;

open ( $$r_newfh , '>', 'testout.txt' ) or die "Could not open file
$!";

### This print gives error
### String found where operator expected at
### C:\develop\NiallPerlScripts\printtest1.pl
### line 18, near "$r_newfh ' in function line 1 '"
### (Missing operator before 'in function line 1 '?)

#print $$r_newfh 'in function line 1 ' , $text , "\n";

### This print works as expected
print $$r_newfh ('in function line 2 ' , $text , "\n");

return;
}
##------------------------------------------------
my @strs = qw(lmn opq rst);

my $newfh;
OpenAndPrint(\$newfh, 'passed string');

## Both prints here work as expected
print $newfh 'somestring ' , $strs[0], ' another ' , $strs[1], "\n";
print $newfh ('yetmore ' , $strs[2]);
close $newfh or die "Could not close file $!";

exit(0);
------------------------------------------------------------------------------------------------------------------

I presume it is something to do with the parantheses forcing list
context but I don't understand why the behaviour is different depending
on whether I am using a file handle or a reference to a file handle.

Can someone explain ?

TIA

Niall
 
M

Mirco Wahab

Thus spoke (e-mail address removed) (on 2006-06-01 16:10):
# print $$r_newfh 'in function line 1 ' , $text , "\n";
print {$$r_newfh} 'in function line 1 ' , $text , "\n";

.... works here.

Regards

Mirco
 
J

John W. Krahn

I have a sub routine which is passed a reference to a scalar. It opens
a file for writing and sets the scalar passed to the value of the
filehandle produced by the open.

I then print to the file from the calling function. This works as
expected

print $newfh 'somestring ' , $strs[0], ' another ' , $strs[1], "\n";

I assumed I should be able to use the same syntax to print to the file
within the subroutine , although of course I need to dereference the
filehandle using $$. However this gave me an error

String found where operator expected at
C:\develop\NiallPerlScripts\printtest1.p
l line 18, near "$r_newfh 'in function line 1 '"
(Missing operator before 'in function line 1 '?)

The print only succeeds if I enclose all the arguments in parentheses.
The parentheses are not required in the calling function

Sorry if this is not crystal clear - Here is a complete program which
demonstrates the problem

----------------------------------------------------------------------------------------------------------------------
use strict;
use warnings;

##------------------------------------------------
sub OpenAndPrint
{

my ($r_newfh, $text) = @_;

open ( $$r_newfh , '>', 'testout.txt' ) or die "Could not open file
$!";

### This print gives error
### String found where operator expected at
### C:\develop\NiallPerlScripts\printtest1.pl
### line 18, near "$r_newfh ' in function line 1 '"
### (Missing operator before 'in function line 1 '?)

#print $$r_newfh 'in function line 1 ' , $text , "\n";

### This print works as expected
print $$r_newfh ('in function line 2 ' , $text , "\n");

return;
}
##------------------------------------------------
my @strs = qw(lmn opq rst);

my $newfh;
OpenAndPrint(\$newfh, 'passed string');

## Both prints here work as expected
print $newfh 'somestring ' , $strs[0], ' another ' , $strs[1], "\n";
print $newfh ('yetmore ' , $strs[2]);
close $newfh or die "Could not close file $!";

You are not passing a value filehandle to the sub so why not just return the
valid filehandle after creating it.

sub OpenAndPrint {
my ( $text ) = @_;
open my $fh, '>', 'testout.txt' or die "Could not open 'testout.txt' $!";
print $fh "in function line 2 $text\n";
return $fh;
}

my $newfh = OpenAndPrint( 'passed string' );



John
 
N

niall.macpherson

John W. Krahn wrote:

You are not passing a value filehandle to the sub so why not just return the
valid filehandle after creating it.


A good point - however in the real program where the function is far
more complex I would prefer not to return the value.

I guess it is a throwback to my days as a 'C' programmer, but I tend to
make most of my subs either return 0 (success) or -1 (failure) , and
any values I require are returned by populating a variable which I pass
by reference to the sub.

Must try to start thinking in Perl not C :)
 
T

Ted Zlatanov

I guess it is a throwback to my days as a 'C' programmer, but I tend to
make most of my subs either return 0 (success) or -1 (failure) , and
any values I require are returned by populating a variable which I pass
by reference to the sub.

It may be easier to return undef for failure. Then you can return 0
if needed, a file handle, or pretty much anything else as a valid
value. You just have to change "if !$result" to "if defined $result".

Ted
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top