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

Per the docs, I was expecting use base to add to the @ISA array of the current package:
use strict; use warnings; use base 'CGI'; print @__PACKAGE__::ISA, $/;
but printing this array shows no values... why?

Replies are listed 'Best First'.
Re: Where is the @ISA array?
by ikegami (Patriarch) on Jan 21, 2009 at 15:18 UTC

    @__PACKAGE__::ISA means @ISA in the package "__PACKAGE__", not the current package.

    use strict; use warnings; use base 'CGI'; print "@main::ISA\n"; # CGI our @ISA; print "@ISA\n"; # CGI my @ourISA = do { no strict 'refs'; @{__PACKAGE__ . '::ISA'} }; print "@ourISA\n"; # CGI

    I wouldn't use base. It's even been obsoleted with parent in newer versions of Perl.

      @__PACKAGE__::ISA means @ISA in the package "__PACKAGE__", not the current package.
      oh, so only with __PACKAGE__-> do I get the current package placed there?

        No, my post shows it being used elsewhere. And here's another:

        $ perl -le'print __PACKAGE__' main

        You wouldn't expect @time::ISA to mean @1232553153::ISA. Same goes for __PACKAGE__. It's a built-in function like time.

        $ perl -le'print CORE::__PACKAGE__' main

        Update: I can override it

        $ perl -wle'BEGIN { *CORE::GLOBAL::__PACKAGE__ = sub () { "abc" }; } p +rint __PACKAGE__' abc

        but I can't call prototype on it

        $ perl -wle'print prototype "CORE::__PACKAGE__"' Can't find an opnumber for "__PACKAGE__" at -e line 1.

        so it's not quite the same as other built-ins. That's probably the only difference.

      Gosh. I didn't know about parent. What was wrong with base?

        It handles load failures badly.

Re: Where is the @ISA array?
by Corion (Patriarch) on Jan 21, 2009 at 15:17 UTC

    __PACKAGE__ is taken verbatim and not interpolated like you seem to think it would be. So you're looking at two different variables, @{"__PACKAGE__::ISA"} and @{"metaperl::ISA"}. Why aren't you simply printing out @ISA? Doing __PACKAGE__ gymnastics just to get at variables seems a little roundabout to me.

      Why aren't you simply printing out @ISA?
      @ISA is a package variable. I am using strict. So I have to package qualify it.
      Doing __PACKAGE__ gymnastics just to get at variables seems a little roundabout to me.
      How would you do it?

        Simply use vars '@ISA';. There is no need to use fully qualified names. In fact, using fully qualified names removes the protection that strict buys you.

        print our @ISA
Re: Where is the @ISA array?
by jeffa (Bishop) on Jan 21, 2009 at 15:16 UTC

    Interesting. I don't have an answer per sey ... but this test seemed to work for me:

    use strict; use warnings; my $bar = bar->new; $bar->foo; package foo; sub new { return bless {}, shift } package bar; use base qw( foo ); use Data::Dumper; sub new { return bless {}, shift } sub foo { print Dumper \@INC }

    DOH! ... silly /me -- of course that works ... i typo'ed and used @INC, not @ISA --- that final method should have been:

    sub foo { print Dumper @__PACKAGE__::ISA }
    Which is empty. :/ I give up.

    UPDATE round 2:
    That final method should have been:

    sub foo { print Dumper @bar::ISA }
    Which does indeed yield the parent class. I am not sure why use base is no longer acceptable for Perl 5. It was supposed to replace the need to push to @ISA directly -- perhaps use base is not going to cut the mustard when roles and traits show up?

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)