Problem using print with a reference to a filehandle

Discussion in 'Perl Misc' started by niall.macpherson@ntlworld.com, Jun 1, 2006.

  1. Guest

    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
     
    , Jun 1, 2006
    #1
    1. Advertising

  2. Mirco Wahab Guest

    Thus spoke (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
     
    Mirco Wahab, Jun 1, 2006
    #2
    1. Advertising

  3. wrote:
    > 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
    --
    use Perl;
    program
    fulfillment
     
    John W. Krahn, Jun 1, 2006
    #3
  4. Guest

    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 :)
     
    , Jun 2, 2006
    #4
  5. Ted Zlatanov Guest

    On 2 Jun 2006, wrote:

    > 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
     
    Ted Zlatanov, Jun 2, 2006
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. keto
    Replies:
    0
    Views:
    1,043
  2. David Cournapeau

    print a vs print '%s' % a vs print '%f' a

    David Cournapeau, Dec 30, 2008, in forum: Python
    Replies:
    0
    Views:
    399
    David Cournapeau
    Dec 30, 2008
  3. dnrg
    Replies:
    5
    Views:
    135
    Matija Papec
    Jun 26, 2003
  4. Replies:
    6
    Views:
    143
    Lars Haugseth
    Nov 22, 2006
  5. Steve Roscio

    Function like print with optional filehandle?

    Steve Roscio, Jan 13, 2009, in forum: Perl Misc
    Replies:
    8
    Views:
    126
    Steve Roscio
    Jan 23, 2009
Loading...

Share This Page