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

Salutations, fellow Monks.

I've been looking at IO::InnerFile and I'm getting a puzzling error:

Can't locate object method "tell" via package "IO::Handle" at /usr/lib +/perl5/site_perl/5.8.0/IO/InnerFile.pm line 233.

I'm basically running the sample code found in the POD for IO::InnerFile:

#!/usr/bin/perl use strict; use warnings; use IO::InnerFile; open(my $fh, "< test_data"); my $inner = IO::InnerFile->new($fh, '100', '50'); while (<$inner>) { print; } close($fh);

As far as I can see, IO::InnerFile isn't inheriting from IO::Handle in any way.
Is there some magic related to the tied filehandle(s) that I'm not aware of?

I've tested this on perl-5.6.1 and perl-5.8.0-thread-multi, both on Linux, with the same results.

I've had a look at the source for the module, and I can't see anything amiss - I feel I'm overlooking something obvious.

Could someone enlighten me to the cause of the wierdness here?

Cheers,

BazB


If the information in this post is inaccurate, or just plain wrong, don't just downvote - please post explaining what's wrong.
That way everyone learns.

Replies are listed 'Best First'.
Re: IO::InnerFile inheriting from IO::Handle?
by ihb (Deacon) on Feb 04, 2003 at 15:34 UTC

    First I'd like to slap you with a customary RTFM, since the first page of the IO::InnerFile documentation states: "Note that FILEHANDLE must be able to seek() and tell(), in addition to whatever other methods you may desire for reading it." ;)

    broquaint offered a solution that manipulated IO::Handle's @ISA. Whilst this works I wouldn't recommend it. Making IO::Handle provide IO::Seekable's methods would perhaps break another class that inherits IO::Handle and uses AUTOLOAD. Or maybe a class inherits something more than IO::Handle, and that other class implements IO::Seekable's methods.

    I suggest making an own class that inherits both IO::Handle and IO::Seekable,

    { package MyHandle; use base qw/ IO::Handle IO::Seekable /; }
    and then bless the filehandle into that, before passing it to &IO::Innerfile::new:   bless $fh => MyHandle::; Now $fh implements what's needed to make IO::InnerFile function.

    Hope I've helped,
    ihb
Re: IO::InnerFile inheriting from IO::Handle?
by bart (Canon) on Feb 03, 2003 at 23:49 UTC
    As far as I can see, IO::InnerFile isn't inheriting from IO::Handle in any way.
    Well... IO::Handle is the default class for an autovivified filehandle. That likely will have something to do with it.
      Even if the default class is IO::Handle, IO::InnerFile has it's own tell method:
      sub tell { return tied(${$_[0]})->{CRPOS}; }

      Any idea why it's not being called?

      Cheers.

      BazB

      If the information in this post is inaccurate, or just plain wrong, don't just downvote - please post explaining what's wrong.
      That way everyone learns.

        Any idea why it's not being called?
        Because it's calling the tell() method on an IO::Handle object, not a IO::InnerFile object, and the reason it's croaking is that IO::Handle doesn't have a tell method. A solution is adding IO::Seekable to IO::Handle's inheritance
        BEGIN { use IO::Seekable; push @IO::Handle::ISA, 'IO::Seekable'; } use strict; use warnings; use Data::Dumper; use IO::InnerFile; open(my $fh, $0); my $inner = IO::InnerFile->new($fh, '100', '50'); while (<$inner>) { print; } close($fh); __output__ Data::Dumper; use IO::InnerFile; open(my $fh, $0

        HTH

        _________
        broquaint