A friend of mine is using a module from a commercial software package in a project. The package, let's call it Foo::Bar, doesn't do exactly what he wants. He wanted to override two subroutines, to change the way their return values are structured. I suggested writing a new module, inherit from the existing one, and override the offending subs. I advised him along these lines:
package Foo::BarMod; use Foo::Bar; @ISA = qw(Foo::Bar); sub stuff { my $self = shift; # Do stuff, overriding Foo::Bar::stuff } # Everything else, including new(), from Foo::Bar 1;

When he tried it out, he was very happy to see that it worked exactly as he had hoped, including stuff().

A few days later, he emailed me saying that one of his scripts wouldn't work, giving him the error:

Undefined subroutine Foo::BarMod::whiz at line 17.

He was quite suprised, because whiz was no different than anything else, he said. (Foo::Bar::whiz exists). Nothing special is being done to it in Foo::BarMod. Thus, it was suprising that it should be the only one to fail: it should be inherited like any other subroutine, right?

Thinking that perhaps something screwy was going on with the object creation (inheriting a constructor is a bit risky, IMHO - call it from your own overidden one, I say) so I enquired about the object ref he was using it on (thinking, perhaps it was mis-blessed?). This is when he mentions that it is a class method, and he didn't have (nor want) an object to use it on.

I asked him more about the method whiz(). It turned out that whiz is a class method - in other words, it does not deal with any specific Foo::Bar, but provides some service of (or to) Foo::Bar 's collectively (or maybe does nothing of the sort, of course:). But, I reasoned, Foo::BarMod ISA Foo::Bar, so any subroutine not found would be looked for in the Foo::Bar namespace, right (AUTOLOADing aside)? Thus this should work:

# call class method whiz() Foo::BarMod::whiz();

Of course, that's exactly how he was getting the error!

While our elder monks probably spotted the problem right away, we mere initiates scrambled for Programming Perl, 2nd Ed., where we found (pg 292) a discussion about how Perl uses @ISA to look for missing methods.

methods, not subroutines. Hmm. So what is the difference between a method and a subroutine? Again, the Camel: two things:

Hmm. Well, it's a class method, so the first one doesn't really apply. Maybe - just maybe - Perl decides whether to consider it a "subroutine" or a "method" (and thus whether to check @ISA) by how you call it - ie, using either the arrow or the "indirect object" syntax. volia! These both work:

Foo::BarMod->whiz(); whiz Foo::BarMod;

but this

Foo:BarMod::whiz;

is just a (fully qualified) subroutine call (and thus, ISA isn't checked, and the sub isn't found.)

So, that's how Perl knows when to check ISA. Meditate upon this, and thus how the ISA mechanism allows us the full benefits of inheritance with object-oriented (ie, method) calls, while leaving alone non-OO (subroutine) calls.


In reply to @ISA, Inheritance, and Class Methods by clwolfe

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.