Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Last Line Read? (Any way to use IO::Handle methods on a "First-Class" Filehandle?)

by blahblahblah (Priest)
on Jun 07, 2007 at 20:51 UTC ( [id://619901]=perlquestion: print w/replies, xml ) Need Help??

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

Hi,

I'm using someone else's code which opens a file for reading like so:

$fh = do {local *FH}; open ($fh, $filename)
I'd never seen that trick before. I found an explanation here: http://perl.plover.com/local.html#3_The_First_Class_Filehandle_Tr.

I want to be able to report the last line number read. I could use $., but I thought IO::Handle's input_line_number method would be better (so I don't have to worry about whether this filehandle was the last one accessed).

However, IO::Handle seems not to like the "do {local *FH};" trick. Here's a small example:

use strict; use warnings; use IO::Handle; my $fh; # $fh = do {local *FH}; #bad open ($fh, './test') or die("open failed: $!"); print "line: " . $fh->input_line_number(); __END__ output with "#bad" commented out: line: 0 output with "#bad" included: Can't call method "input_line_number" without a package or object refe +rence at test line 10.
I have two easy workarounds -- use $. carefully, or modify the original code -- but I was wondering if there's a cleaner way of getting the line number?

Thanks,
Joe

Replies are listed 'Best First'.
Re: Last Line Read? (Any way to use IO::Handle methods on a "First-Class" Filehandle?)
by shmem (Chancellor) on Jun 07, 2007 at 21:04 UTC
    Quick fix: make your $fh into an IO::Handle object:
    # odd way to count lines of a file :-) use strict; use warnings; use IO::Handle; my $fh = IO::Handle->new; #good # $fh = do {local *FH}; #bad open ($fh, './test') or die("open failed: $!"); 1 while <$fh>; print "line: " . $fh->input_line_number(); __END__

    $. has its drawbacks - it contains the line number of last filehandle accessed. So there's no safe evaluation at a distance.

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: Last Line Read? (Any way to use IO::Handle methods on a "First-Class" Filehandle?)
by ysth (Canon) on Jun 08, 2007 at 05:53 UTC
    You can't do $fh->input_line_number, but you can do (\$fh)->input_line_number.
      I'm sorry, but I'm confused with your statement.
      $ perl -MIO::Handle -le 'open my $fh, "<", shift or die $!; print $fh- +>input_line_number while <$fh>' a_file_name 1 2 3 4 . . . $ perl -MIO::Handle -le 'open my $fh, "<", shift or die $!; print (\$f +h)->input_line_number while <$fh>' a_filename REF(0x99d7cdc) Can't call method "input_line_number" without a package or object refe +rence at -e line 1, <$fh> line 1. # $fh = do {local *FH}; #bad $ perl -MIO::Handle -le 'my $fh = do {local *FH}; open $fh, "<", shift + or die $!; print (\$fh)->input_line_number while <$fh>' a_file_name GLOB(0x846ccdc) Can't call method "input_line_number" without a package or object refe +rence at -e line 1, <FH> line 1.
      Update: Added example code with "#bad" mark

      Open source softwares? Share and enjoy. Make profit from them if you can. Yet, share and enjoy!

        Always always always use warnings; teach your fingers to type -wle, not -le. You are doing (print(\$fh))->input_line_number there, not print((\$fh)->input_line_number).

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://619901]
Approved by GrandFather
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (6)
As of 2024-04-23 07:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found