PyrexKidd has asked for the wisdom of the Perl Monks concerning the following question:

How do I print to a file from a sub routine when using strict subs?

I have a program that opens a file in the main portion of the code and then calls a sub that needs to print to the same file as well. I would like to avoid opening and closing the file every time I have to write to it.

In Java I would open the file in the main sub and then pass the file as an object to whatever sub nees to print to it.


public main(){ FileWriter file = new fileWriter();"file.txt"); print_sub(file); } private print_sub(FileWriter file){ //do something with the file }

is there a way to do this in Perl? thanks in advance

Replies are listed 'Best First'.
Re: Printing to a File from Sub
by Corion (Patriarch) on Aug 26, 2010 at 17:51 UTC

    In Perl, you do it the same.

    my $logfile = 'file.txt'; open my $log_fh, '>>', $logfile or die "Couldn't open '$logfile': $!"; sub print_sub { my ($log) = @_; print {$log} "Starting work\n"; }; ... print_sub($log_fh);

    But maybe you want Log::Log4perl?

Re: Printing to a File from Sub
by suaveant (Parson) on Aug 27, 2010 at 14:56 UTC
    Of course, if your code is OO you could also store the filehandle in the object to prevent the need for passing it around, even better create a method to retrieve the fh that created it on the first request. Perl filehandles when create as Corion exhibited can be passed around like any scalar, pretty much. Or you could even create a closure to handle all prints:
    { my $fh; open($fh,'>',$file); sub print_to_fh { print $fh @_; } }
    As always, TIMTOWTDI :)

                    - Ant
                    - Some of my best work - (1 2 3)

      here is code I am trying to use:

      #!/usr/bin/perl use strict; use warnings; open my $fhout, '>', "./test_out.file" || die "$!"; &test_print($fhout); sub test_print{ my $fhout = @_; print {$fhout} "this is a test\n"; } close $fhout;

      and here is the error message I keep getting:

      ~$ perl Can't use string ("1") as a symbol ref while "strict refs" in use at t line 11.
      What is going on here? am I just missing something? Thanks for the assist.
        You should either use
        open my $fhout, '>', "./test_out.file" or die "$!";
        open (my $fhout, '>', "./test_out.file") || die "$!";
        . The code you posted is parsed as
        open (my $fhout, '>', ("./test_out.file" || die "$!"));
        which is definitely not what you want.

        To avoid the error you reported, though, use

        my ($fhout) = @_;
        my $fhout = shift;
        Also note that the ampersand sign & is not needed when calling a sub (see perlsub).

        Putting the filehandle in parens told Perl that it is the argument to print, and so you wanted to print it to STDOUT - which is not what you wanted. You wanted to say
        print $fhout "this is a test\n";
        It should also be noted that the variable $fhout is actually still in scope in your subroutine, so you technically could just use it. It is, however, better practice to pass it in.

        Edit: choroba is correct as s/he notes below. I did mistake the curlies for parens.