Pretending to be someone I am not

brian_d_foy on 2003-11-26T16:32:13

A couple weeks ago, I had an idea as I was walking across the desert. If I could pretend to be base.pm, I could do whatever I wanted whenever a module did a use base, and along the way I could map the @ISA tree. Now, this was just for fun, since I know that every module does not use base.pm.

First, the code:

#!/usr/bin/perl -w
use strict;

$INC{'base.pm'} = 1;

package base;

sub import { my $class = shift; my $caller = ( caller )[0];

$main::Isa{$caller} = [ @_ ];

foreach my $package ( @_ ) { eval { eval "require $package" }; } }

package main;

eval { eval "require $ARGV[0]" };

delete $INC{'base.pm'};

display( $ARGV[0], 0 );

sub display { my( $key, $level ) = @_;

my $space = "\t" x ($level + 1); print "$space$key\n"; return unless UNIVERSAL::isa( $main::Isa{$key}, 'ARRAY' ); foreach my $key ( sort { lc $a cmp lc $b } @{ $main::Isa{$key} } ) { display( $key, $level + 1 ); } }


First, I have to make Perl think it has already loaded base.pm, otherwise it will load it when a module tries to use it. The %INC hash keeps track of that, so I create the right key and give it a true value (although you typically find path names there).

Second, I create my base package and its import routine. This is the subroutine that perl calls when I use base qw(foo bar). I do some magic to pull out @ISA, and store it. I do everything with full pacakge specifications because somewhere along the way I was worried about things going kablooey with all my shenanigans (for instance, can I trust vars.pm when I am fooling around like this?)

Third, I go back to the main package, load the module named on the command line, and I am off to the races. Once I am all done, I pretty print the stuff in @Inc.

Fourth, I realize although I have a lot of fun, this is a really stupid thing to do and it is not very illuminating. It is more like an extra credit homework problem than a useful task.


Just push a subref into @INC

merlyn on 2003-11-26T16:45:18

You can push a smart subref into @INC that noted the activity and then figured out what actually was needed, kinda like an AUTOLOAD.

Re:Just push a subref into @INC

chromatic on 2003-11-26T17:16:14

I tried pushing a subref into @ISA once. I was sad when it didn't work. Someday, I'll look at the core about it.

Re:Just push a subref into @INC

brian_d_foy on 2003-11-26T22:42:04

How would that work? I mean, I know I can do just about anything with a subref, but I have never played around with those. They sound like the spawn of satan, sort of like pseudo-hashes.