On Tue, Apr 17, 2001 at 03:58:51PM +0100, Piers Cawley wrote:
> You might want to see if you can spot places where @ISA gets messed
> with at runtime as well. Just a thought.
That's a bit harder since the cannonical subclassing...
package Foo;
@ISA = qw(Bar);
is at run-time... from the point of view of the calling program.
However, its compile-time to the module.
Anyhow, I think we can get away with checking for anything that alters
@ISA inside a subroutine (in addition to the other checks, such as
looking for uses of non-exported variables). Noting uses of a certain
variable inside a subroutine isn't that hard. The problem is finding
all possible opcodes that can modify a variable.
Hmmm... this would be considered unpredictable...
if( eval "require Crypt::Blowfish" ) {
@ISA = qw(Crypt::Blowfish);
}
elsif( eval "require Crypt::Blowfish_PP" ) {
@ISA = qw(Crypt::Blowfish_PP);
}
So maybe its just "more than one modification of @ISA in any package"
with @ISA mods inside subroutines getting special attention.
Another bit of unpredictability (or just plain questionable practice)
is code that scans @ISA instead of using UNIVERSAL::isa(). Or code
that does: C<ref $foo eq 'Some::Class'> instead of
$foo->isa('Some::Class'). Such code calcifies your hierarchy. In
this case, anything that looks at @ISA should probably be noted and
anything that sees if a reference equals something that's not a built
in type should also be noted.
That actually makes the @ISA scan alot easier. If @ISA is mentioned
more than once in any package (use vars aside) its noted. The ref()
check is also simple in its basic form, although regexes will be a
problem.
--
Michael G. Schwern <[EMAIL PROTECTED]> http://www.pobox.com/~schwern/
Perl6 Quality Assurance <[EMAIL PROTECTED]> Kwalitee Is Job One
the chair. it wants to die. oh no! she sees me! she attacks!