从代码中获取方法的源文件位置

时间:2018-02-05 09:16:26

标签: perl

perl 是否有办法获取方法的源文件位置? 例如,如果方法 - 来自模块“methodModule”的“myMathod”是从perl脚本调用的 - “myScript”。然后让'myModule'驻留在路径:/ path / to / myModule, 那么有办法做这样的事情: getSourceFileLocationOf(“methodModule”)==“/ path / to / myModule”

2 个答案:

答案 0 :(得分:2)

您可以查看perldoc perlvar中记录的%INC哈希:

  

%INC

     

hash%INC包含通过do,require或use运算符包含的每个文件名的条目。键是您指定的文件名(模块名称转换为路径名),值是找到的文件的位置。 require运算符使用此哈希来确定是否已包含特定文件。

     

如果文件是通过钩子加载的(例如子程序引用,请参阅require以获取这些钩子的描述),默认情况下,此钩子插入%INC而不是文件名。但请注意,挂钩可能已自行设置%INC条目以提供更具体的信息。

这是一个简单的例子:

perl -e 'use WWW::Mechanize; print $ENV{"WWW/Mechanize.pm"} . "\n";

<强>输出

/usr/local/share/perl5/WWW/Mechanize.pm

根据@zdim的建议,还可以使用相当用户友好的Sub::Identify

use Sub::Identify qw( :all );
use WWW::Mechanize;

my ($file, $line) = get_code_location( \&WWW::Mechanize::get );
print "File $file, Line $line\n";'

<强>输出

File /usr/local/share/perl5/WWW/Mechanize.pm, Line 106

答案 1 :(得分:1)

要查找找到该方法的包:

{ provide: ErrorHandler, useClass: CustomErrorHandlerX }

注意:如果方法是自动加载的,则不起作用。

要查找编译方法的包:

use mro          qw( );
use Scalar::Util qw( blessed );

sub get_method_package {
   my ($obj, $method_name) = @_;
   defined( my $class = blessed($obj) )
      or return undef;

   for my $pkg_name (@{ mro::get_linear_isa($class) }) {
      my $pkg = do {
         no strict qw( refs );
         *{ $pkg_name.'::'.$method_name }
      };
      return $pkg_name if *{$pkg}{CODE};
   }

   return undef;
}

注意:如果可以正确覆盖,则仅适用于自动加载的方法。

注意:适用于在XS中实现的方法。

要查找编译方法的文件:

use B qw( svref_2object );

sub get_method_package {
   my ($obj, $method_name) = @_;
   my $method_ref = $obj->can($method_name)
      or return undef;

   return svref_2object($method_ref)->GV->STASH->NAME;
}

注意:如果可以正确覆盖,则仅适用于自动加载的方法。

注意:仅适用于Perl方法。对于在XS中实现的方法,它返回没有路径的.c文件的名称。例如,为use B qw( svref_2object ); sub get_method_file { my ($obj, $method_name) = @_; my $method_ref = $obj->can($method_name) or return undef; return svref_2object($method_ref)->FILE; } 返回XS.c。 (这可能因系统和XS加载程序而异。)