in reply to Re: Passing a file handle to a sub. I still don't get it.
in thread Passing a file handle to a sub. I still don't get it.

Thank you both for your replies. So, I tried IO::File, and now $_ in the while loop contains "IO::File=GLOB(0xa1f08c4)". I hope I'm not being terribly dim here - I really appreciate your help, but this doesn't quite get me there yet. Any other hints?
  • Comment on Re^2: Passing a file handle to a sub. I still don't get it.

Replies are listed 'Best First'.
Re^3: Passing a file handle to a sub. I still don't get it.
by ysth (Canon) on Jun 09, 2005 at 19:21 UTC
    What tlm neglected to mention was what you should do :)

    Because <> can do two different things, readline and glob (and in your case is doing the wrong one), you should explicitly say while(readline($opts{-handle})).

      So, if I changed the sub to have a local $fh it would do the right thing?
      sub from_handle { my $self = shift; my %opts = @_; my $fh = $opts{-handle}; while (<$fh>) { #... and here we're supposed to read from FH } }
        Yes, that would work, but why not just use readline() directly?
Re^3: Passing a file handle to a sub. I still don't get it.
by tlm (Prior) on Jun 09, 2005 at 19:04 UTC

    What exactly do you have in the <> brackets? Can you post the code?

    Also, now that you're using IO::File you can use its getline method instead of angle brackets to do linewise input. This eliminates the ambiguity with file globbing. See the docs for IO::File parent class, IO::Handle.

    the lowliest monk

      Okay, so here's the whole code. This sub is the one calling the parser:
      sub parse { my $self = shift; my @opts = @_; my %opts; if ( ! @opts || scalar @opts % 2 ) { $self->COMPLAIN("bad number of arguments."); return; } else { %opts = @opts; if ( ! $opts{-format} || ! grep(ucfirst($opts{-format}), @pars +ers) ) { $self->COMPLAIN("no valid format specified."); return; } if ( $opts{-file} && ( ! -T $opts{-file} || ! -r $opts{-file} +) ) { $self->COMPLAIN("file not found, not a text file, or not r +eadable"); return; } elsif ( ! $opts{-file} && ! $opts{-string} ) { $self->COMPLAIN("no data source specified."); return; } my $lib = ref $self; $lib .= '::' . ucfirst($opts{-format}); eval "require $lib"; my $parser = new $lib; if ( $opts{-file} && $parser->can('from_handle') ) { open(FH, $opts{-file}); $opts{-handle} = \*FH; return $parser->from_handle(%opts); } if ( $opts{-string} && $parser->can('from_string') ) { return $parser->from_string(%opts); } $self->COMPLAIN("the parser can't handle the data source speci +fied"); return; } }
      The call is 9 physical lines from the bottom. And here's the one who gets called:
      sub from_handle { my $self = shift; my %opts = @_; my $taxa = new Phylo::Taxa; my $version = $self->VERSION; while (<$opts{-handle}>) { if ( $_ ) { my $taxon = new Phylo::Taxa::Taxon; my $date = localtime; my $description = qq{Read from $opts{-file} using Phylo ve +rsion $version on $date}; $taxon->name($_); $taxon->desc($description); $taxa->insert($taxon); } } return $taxa; }
      And in the second block $_ == GLOB(0xa0bb570).

        What happens if you replace the while line in from_handle with

        while ( defined( $_ = $opts{-handle}->getline ) ) {
        ?

        the lowliest monk