Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Re: What's the right way to write a method which returns one line at a time from a file?

by Fletch (Chancellor)
on Nov 22, 2020 at 04:41 UTC ( #11124002=note: print w/replies, xml ) Need Help??


in reply to What's the right way to write a method which returns one line at a time from a file?

Just stash the handle in a member variable and when you call get_next_line call readline on the stashed handle.

package MyFile; use Moo; has _fh => { is => 'rw' }; sub BUILD { my( $self, @args ) = @_; $self->_fh( do { open( my $fh, q{<}, $self->frobnicate_path() ) or die qq{Can't open frobnicated path: $!\n}; $fh; } ); return; } sub frobnicate_path { my( $self ) = shift; return qq{WHATEVER.txt}; } sub get_next_line { my( $self ) = shift; return readline( $self->_fh ); } sub DEMOLISH { if( $self->_fh ) { close( $self->_fh ) or warn qq{Problem closing frobnicated path: $ +!\n}; } } 1; __END__

Edit: fixed readline in get_next_line and added frobnicate_path stub.

The cake is a lie.
The cake is a lie.
The cake is a lie.

  • Comment on Re: What's the right way to write a method which returns one line at a time from a file?
  • Select or Download Code

Replies are listed 'Best First'.
Re^2: What's the right way to write a method which returns one line at a time from a file?
by Cody Fendant (Friar) on Nov 22, 2020 at 06:24 UTC

    Thanks, that kickstarted my brain.

    I'm too old-school to do it your way but I did it this way in the end:

    sub get_filehandle { my $self = shift; $self->{file} = shift; open( my $fh, '<', $self->{file} ) or die "can't open $self->{file}"; return $fh; } sub get_lines { my $self = shift; $self->{file} = shift; ### get the filehandle if we don't already have one unless ( $self->{file_handle} ) { $self->{file_handle} = $self->get_filehandle( $self->{file} ); } if ( my $line = readline( $self->{file_handle} ) ) { return $line; } else { return; } }
      if ( my $line = readline( $self->{file_handle} ) ) { return $line; } else { return; }

      I appreciate old-school, but I think the quoted code will fail to return the last line of a file if it is '0' with no terminating newline. I haven't tested it, but wouldn't

      if (defined(my $line = readline( $self->{file_handle} ))) { return $line; } else { return; }
      or even just
          return readline($self->{file_handle});
      (readline returns undef at eof) be better?


      Give a man a fish:  <%-{-{-{-<

        Thanks for your contribution, sorry for the late response. In my case I happen to know that will never happen but perfectly valid point. My code is working but I will improve it with your suggestion.

      $self->{file_handle} = $self->get_filehandle( $self->{file} );

      You can't reload or open a new file using the above. Additionally, you can end up having a discrepancy whereas $self->{file} points to one file and $self->{file_handle} to another. If you want that functionality, then I would set file_handle inside get_filehandle() with appropriate logic.

        I always run this code on one unique file name at a time, but thanks for the contribution, I appreciate it.

      Not to the topic, but there should NEVER an else after a return/exit/croak/die.

      A return/die/exit/croak will end the current scope immediately, making the else obfuscating the code that follows, as the code after the else block will never be executed if the if branch is taken.

      If I were a code reviewer, that code would be vetoed.


      Enjoy, Have FUN! H.Merijn

        That is ridiculous: the else block is only executed if the condition on the if is false. Since the return is in the if block, it is only executed if the condition tested evaluates to true, which means that the else would never be executed anyway.

        This is a perfectly legitimate construct when different return values must be produced in different conditions, or when an early exit is needed under some conditions.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://11124002]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (3)
As of 2021-01-22 00:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Notices?