Re: How can I find out where a subroutine is defined?

From: Billy N. Patton (b-patton_at_ti.com)
Date: 09/30/04


Date: Wed, 29 Sep 2004 17:16:19 -0500
To: Stan Brown <stanb@panix.com>


Stan Brown wrote:
> I had a machine crash, and I'm trying to recover from the crash. I't a
> FreeBSD machine, so I reinstalled a newer version of the OS, and perl and
> perl modules using the ports system.
>
> Among the modules thta this perl script uses are Parse::Lex , and
> Parse::FixedLength. When run the scrpt it dies on undefiend subroutine
> parse. Now this script runs on other machines with older versions of the
> modules, and there is no subroutine parse defined in it.
>
> My current working theory is that the interface to one of the modules I sue
> has changed.
>
> Given that it _does_ work on other machines, how can I find out (on them)
> what is actually being called here?
>
>
>

Attached is a routine I have in my base module. You'll have to do some
minor edits, but I think it is what you want.

-- 
    ___  _ ____       ___       __  __
   / _ )(_) / /_ __  / _ \___ _/ /_/ /____  ___
  / _  / / / / // / / ___/ _ `/ __/ __/ _ \/ _ \
/____/_/_/_/\_, / /_/   \_,_/\__/\__/\___/_//_/
            /___/
Texas Instruments ASIC Circuit Design Methodlogy Group
Dallas, Texas, 214-480-4455,  b-patton@ti.com

sub display_Perl_modules
{
  cdmgOut(" Perl modules used:\n");
  my $cwd = getcwd();
  $cwd =~ s|^/tmp_mnt||;
  my( $i, $module, $version, @modules, %dirs, $dir );
  @modules = sort keys %INC;
  for ( $i = 0; $i < @modules; ++$i )
  {
    ;# first print module names which are fully qualified paths
    if ( $modules[$i] =~ m|^/| )
    {
      cdmgOut(" $modules[$i]\n");
      splice( @modules, $i, 1 ); # remove this from array
      redo;
    }
    if ( $INC{$modules[$i]} =~ /^(\S+)\/$modules[$i]$/ )
    {
      push( @{$dirs{$1}}, $modules[$i] );
    }
    else
    {
      push( @{$dirs{$cwd}}, $modules[$i] );
    }
  }
  foreach $dir ( sort keys %dirs )
  {
    cdmgOut(" $dir:\n");
    foreach ( @{$dirs{$dir}} )
    {
      $version = "";
      if ( /^([^\.\/]\S*)\.p[lm]$/ )
      {
        $module = $1;
        $module =~ s|/|::|g;
        ;# don't do this step if the directory name includes characters which
        ;# are not legal in Perl variable names; otherwise you'll get an error here
        if ( $module =~ /^[A-Za-z:_0-9]+$/ ) {
            eval( "\$version = \" (version \$${module}::VERSION)\" if defined \$${module}::VERSION" );
            eval( "\$version = \" (version \$${module}::VERSION, updated \$${module}::DATE)\" " .
                  "if ( defined \$${module}::VERSION and defined \$${module}::DATE )" );
        }
      }
      cdmgOut( " $_$version\n");
    }
  }
}