http://www.perlmonks.org?node_id=724783

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

I need to:

1) open a file
2) print stuff to file
3) call a subroutine that also prints to that file

So I thought I ought to do it like this:

my $filepath = 'foo.txt'; open my $FOOFILE, '>>', $filepath or die "Couldn't open $filepath \n"; print $FOOFILE "First line of text.\n"; for ( my $outer_loop = 1 ; $outer_loop <= 5 ; $outer_loop++ ) { #do a bunch of stuff &do_other_stuff; if ( $outer_loop == 5 ) { print $FOOFILE "The end."; close $FOOFILE; } } sub do_other_stuff { for ( my $inner_loop = 0 ; $inner_loop < 5 ; $inner_loop++ ) { if ( $inner_loop == 3 ) { print $FOOFILE "A match!\n"; } }
My question is whether this is poor form. Should I close and reopen the file in the sub instead of just leaving it open? More like this:
sub do_other_stuff { open $FOOFILE, '>>', $filepath or die "Couldn't open $filepath \n"; for ( my $inner_loop = 0 ; $inner_loop < 5 ; $inner_loop++ ) { if ( $inner_loop == 3 ) { print $FOOFILE "A match!\n"; } } close $FOOFILE; }
Thanks,

zod

Replies are listed 'Best First'.
Re: Keep file open for sub call?
by GrandFather (Saint) on Nov 20, 2008 at 03:12 UTC

    Why not:

    my $filepath = 'foo.txt'; open my $FOOFILE, '>>', $filepath or die "Couldn't open $filepath: $!\ +n"; print $FOOFILE "First line of text.\n"; for (1 .. 5) { #do a bunch of stuff do_other_stuff ($FOOFILE); } print $FOOFILE "The end."; close $FOOFILE;

    Unless there are multiple applications that may be updating the file and that are fighting for locks on it (in which case you are in a whole other world of pain) there is no reason to close the file. Opening and closing a file can be relatively expensive so avoiding that cost is generally a Good Thing™.

    Note that you should avoid using global variables in subs ($FOOFILE for example) and generally you shouldn't call subs using the &sub syntax. Also, use the Perl for loop rather than the C for loop where you can.


    Perl reduces RSI - it saves typing
      Thanks for the input.
Re: Keep file open for sub call?
by lostjimmy (Chaplain) on Nov 20, 2008 at 03:15 UTC

    Update: GrandFather beat me to it!

    In my opinion, I don't think you should close and then reopen the file in the subroutine.

    The only things I would change would be to pass the file handle to the sub, use foreach style loops rather than the c-style loops you are using (for my $inner_loop (0..4)), and change &do_other_stuff to do_other_stuff()

Re: Keep file open for sub call?
by toolic (Bishop) on Nov 20, 2008 at 14:55 UTC
    Assuming the amount of data you are writing to a file is relatively small, another approach is to accumulate the lines of data into an array, then open/write/close the file in one place:
    my @lines; push @lines, "First line of text.\n"; # keep pushing lines of text into the array my $filepath = 'foo.txt'; open my $FOOFILE, '>>', $filepath or die "Couldn't open $filepath: $!" +; print $FOOFILE $_ for @lines; close $FOOFILE;

    You could pass the array as a reference to your sub.