FAQ
The "@ISA corrupted" error has been the bane of my existence for
several years now, but I think I've finally nailed it.

EmbperlObject.pm has code to modify the @ISA variable in a package to
make it a base class of a particular document. It executes that code
if the @ISA array is empty. BUT certain combinations of recursive
Execute({ isa => ... }) commands can create a situation where a
document already has an @ISA, but *doesn't* inherit from the class
being added. How it got that way took me a bit longer.

Here's the sequence that reliably triggered the error.

My object_base is Template.html.

HTML::Embperl::Execute got called by EmbperlObject.pm(277) with Template.html

Template.html did an Execute({object => '*', import => 0}) which
executed HTML::Embperl::Execute on index.html from
EmbperlObject.pm(294).

index.html did an Execute({isa => 'tools.epl', import => 0}). That
called HTML::Embperl::Execute directly.

tools.epl did an Execute({isa => 'SiteInit.html', input => 0}). That
called HTML::Embperl::Execute directly.

SiteInit.html did an isa on help.html.

Now HTML::EmbperlObject called HTML::Execute on Template.html from
line 314. It wanted to bless the HTML::Embperl::Req as an
HTML::Embperl::DOC::_2 (index.html), but that already has an ISA that
referenced an HTML::Embperl::DOC::_3 (tools.epl), and that has an ISA
that referenced an HTML::Embperl::DOC::_4 (SiteInit.html) and so on.
Nobody there references DOC::_1 (Template.html). And DOC::_1 is the
only one that ISA HTML::Empberl::Req.

Initially I fixed half the problem, but there are two places where
EmbperlObject sets the ISA, and they are both wrong. The first case
sets up the request handler parent (usually HTML::Embperl::Req). It
turns out that the way it does this means that your template calls
Execute({ isa => ... }) you will either lose the isa, or overwrite
the inheritance of the request class. In general multiple
inheritance isn't working.

The right solution seems to be just to call UNIVERSAL::isa and *add*
the new class to @ISA.

As a side effect this gives me something I have been wanting for a
long time but could never get to work. Your Embperl template can
isa=> load helper files and (because '*' inherits from the template)
the referenced file will automatically pick up the inheritance.

Template.html
Execute({isa => 'helper.epl', import => 0});
Execute('*');
* is now a helper.epl
I actually structure my templates differently, making them nothing
but subroutines:
$page = Execute({ object => '*', import => 0 });
so that I can then scatter calls to
$page->title()
and the like throughout the Template. But those pages always had to
execute the same base files over and over--now they don't.

I'm pretty sure this is the right patch, but I'd like feedback.
Also, I'm not sure whether the right approach is to use "push" or
"unshift". As I did it, it looks like the first @isa in the template
is the first on the stack, and the Req object is last. The latter
sounds right, I'm not sure about the former.

*** EmbperlObject.pm Sat Sep 1 17:31:10 2001
--- /Library/Perl/darwin/HTML/EmbperlObject.pm Fri Nov 28 15:14:45 2003
***************
*** 281,289 ****
#use strict ;
}
no strict ;
! if (!@{"$basepackage\:\:ISA"})
{
! @{"$basepackage\:\:ISA"} = ($req -> {object_handler_class} || 'HTML::Embperl::Req') ;
}
use strict ;

--- 281,290 ----
#use strict ;
}
no strict ;
! my $reqclass = $req -> {object_handler_class} || 'HTML::Embperl::Req';
! if (!UNIVERSAL::isa($basepackage, $reqclass))
{
! push(@{"$basepackage\:\:ISA"}, $reqclass);
}
use strict ;

***************
*** 301,309 ****
}

no strict ;
! if (!@{"$package\:\:ISA"})
{
! @{"$package\:\:ISA"} = ($basepackage) if ($package ne $basepackage) ;
}
use strict ;

--- 302,310 ----
}

no strict ;
! if (!UNIVERSAL::isa($package, $basepackage))
{
! push(@{"$package\:\:ISA"}, $basepackage);
}
use strict ;

--
Kee Hinckley
http://www.messagefire.com/ Next Generation Spam Defense
http://commons.somewhere.com/buzz/ Writings on Technology and Society

I'm not sure which upsets me more: that people are so unwilling to accept
responsibility for their own actions, or that they are so eager to regulate
everyone else's.

---------------------------------------------------------------------
To unsubscribe, e-mail: embperl-unsubscribe@perl.apache.org
For additional commands, e-mail: embperl-help@perl.apache.org

Search Discussions

Discussion Posts

Follow ups

Related Discussions

Discussion Navigation
viewthread | post
posts ‹ prev | 1 of 3 | next ›
Discussion Overview
groupembperl @
categoriesmodperl, perl
postedNov 28, '03 at 8:34p
activeNov 29, '03 at 6:38p
posts3
users2
websiteperl.apache.org

2 users in discussion

Kee Hinckley: 2 posts Gerald Richter: 1 post

People

Translate

site design / logo © 2022 Grokbase