develooper Front page | perl.perl5.porters | Postings from May 2008

Re: Recursive inheritance detected while looking for method - Why?

Thread Previous
Nicholas Clark
May 8, 2008 04:18
Re: Recursive inheritance detected while looking for method - Why?
Message ID:
On Wed, May 07, 2008 at 10:52:12PM +0100, Lyle wrote:

> Looking for the objects method will first go:-
> d, a, c, a, b, a
> And so on with needless re-checks in packages it's already been too.
> Of course if you set 'a' ISA 'b', then it's going to go into an infinate 
> loop and you'll get the "Recursive inheritance detected while looking 
> for method" error.
> What I don't understand is.. and forgive me if I'm missing something.. 
> why doesn't the method lookup for an object remember which packages it's 
> already been to and no recheck them. In the examples above wouldn't this 
> be quicker? It would also allow recursive inheritance, which I'm 
> guessing is a bad thing, but could be useful in places.

The inheritance code changed for 5.10, thanks to Brandon Black, who put a lot
of work into making C3 method resolution order efficient. Until then, the code
in question hadn't been changed for 10 years (no bug fixes needed either) so
it's not something we're all familiar with.

I think that the order of ISA for a package was always cached, and the lookup
for methods is cached. Pre 5.10, the cache was flushed if any subroutine was
defined. Brandon changed it so that cache flushes are confined to the affected
packages, something which takes more bookkeeping, but is definitely worth it
for C3.

Looking at Brandon's implementation in mro.c, the ISA resolution for the old
style (DFS - Depth First Search) does strip out packages already seen, so
there aren't now needless re-checks. However, grepping for the error about
"Recursive inheritance":

    if (level > 100)
        Perl_croak(aTHX_ "Recursive inheritance detected in package '%s'",

(which is the same code in 5.8.x in universal.c) it seems that "recursion"
isn't actually detected, it's merely inferred from a very very deep recursion.

Yes, I guess you're right - for the DFS scheme (or at least, a modified DFS
scheme) one could define some rules for recursive inheritance. And it is
now (almost) possible to plug in custom MROs. So it would be possible to
write one on CPAN. But I really can't think of a great use case where a
recursive inheritance scheme would save the day where others failed.

Nicholas Clark

Thread Previous Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About