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

is there a built in way to track the number of times a \n is printed to a filehandle? Example:
open OUT, ">track.txt" print OUT "this is one line\n"; print OUT "this\n is several\n lines\n in one print";

in the above example i would want some counter variable incremented everytime a \n is printed. The end goal is that when a cetain number of lines is reached i want to close the file handle, and open a new one with the same name that points to a different file.

thanks in advance

Replies are listed 'Best First'.
Re: Tracking Lines Printed to a FileHandle
by davido (Cardinal) on Dec 02, 2004 at 16:22 UTC

    You either have to track that explicitly, with some sort of counter, possibly in your printing loop, or you need a little smoke and mirrors magic.

    If you are a proponent of magic, you can tie your filehandle to a class that keeps track of the number of lines printed for you. You could then query the filehandle object to determine if the max number of lines has been reached, or if it's nearing, etc.

    See tie, and perltie for details on tieing filehandles. The details are a little obscure at first, but once you get the hang of it you can create some interesting spells.


    Dave

Re: Tracking Lines Printed to a FileHandle
by fglock (Vicar) on Dec 02, 2004 at 16:24 UTC
Re: Tracking Lines Printed to a FileHandle
by simonm (Vicar) on Dec 02, 2004 at 16:24 UTC
    No, I don't think there's any built-in way to do this.

    If you can't count the lines before calling print, it should be feasible to create a tied handle class that counts them as they are printed.

Re: Tracking Lines Printed to a FileHandle
by waswas-fng (Curate) on Dec 02, 2004 at 17:43 UTC
    You could make a sub that does the counting and dirty work of opening new files, closing full files, printing the lines to the files and call that in place of print OUT "lala\n"; in your code...


    -Waswas
Re: Tracking Lines Printed to a FileHandle
by davido (Cardinal) on Dec 03, 2004 at 05:13 UTC

    The more I think about it, the more I think that for most needs it's probably best to just count newline characters immediately prior to printing:

    $count += $print_string =~ tr/\n//; print OUT $print_string;

    ...why get tricky with something so easy, right?


    Dave

      Yes after looking at the project it was much simpler to just count the newlines before each print, and that is what I wound up doing. Thanks for the suggesstions and help. Here is a sample of what i wound up doing as far as the same FILEHANDLE, different file goes:
      $filename = "MyJScript01.txt"; push(@filenames,$filename); $filenumber = 1; #variable to track the filenames format: MyJscript#.t +xt where # is a number open (OUT,">$filename"); print OUT "<script language='JavaScript'>\n"; print OUT "function whichMapper(obj){\n"; print OUT "if(obj.selectLSO.selectedIndex == 1){\n"; $lineCounter = 3; #Track the number of newlines printed to the JS file (other code with many prints each line incrementing $linecounter)... if($lineCounter > 1000){ close OUT; $filenumber += 1; $filename = "MyJScript0".$filenumber.".txt"; push(@filenames,$filename); open (OUT,">$filename"); $lineCounter = 0; } } print OUT "}\n"; print OUT "</script>\n"; close OUT; (at the end I do stuff with the files created)...
      This is a snippet from a larger program, but basically what I was doing was creating a javascript file based on some data in a db. The file was being included into a dynamic webpage. The file apparently got too large an cause a buffer overrun in the include directive of the web server we use. so I just decided to break the file up into smaller files and include them in order. Wound up working fine.
Re: Tracking Lines Printed to a FileHandle
by graff (Chancellor) on Dec 03, 2004 at 04:02 UTC
    waswas-fng's idea is the first thing I would try; something like this:
    my $max_line_count = $whatever; my $file_count = my $line_count = 0; my $outfh; sub printAndCount { local $_ = shift; my $lines2print = tr/\n/\n/; # simple way to count \n's if ( $file_count == 0 or $line_count + $lines2print > $max_line_count ) { close $outfh if ( $file_count ); open $outfh, sprintf( ">track%03d.txt", ++$file_count ) or die + "open failed: $!"; } print $outfh; $line_count += $lines2print; }
    Note that this idea doesn't exactly match what you said:
    The end goal is that when a cetain number of lines is reached i want to close the file handle, and open a new one with the same name that points to a different file.
    You can't "open a different file" using the same file name over and over. If you don't use a different file name each time, you'll simply be deleting the last set of lines that you wrote as soon as you open a "new" file.
Re: Tracking Lines Printed to a FileHandle
by Anonymous Monk on Dec 04, 2004 at 04:23 UTC
    There is a variable that tracks the current line number. It's from the time when perl had to format reports on line printers and had to skip the fold at the right time. Could you use the whole report printing mechanism?