我有一个调用该函数的代码。但我不知道这个功能属于哪个模块。我需要它来修改这个功能。
我该如何检查?
答案 0 :(得分:30)
Devel::Peek
模块非常方便获取有关变量的各种信息。你可以用它做的一件事是转储对子程序的引用并得到它来自的glob的名称:
$ perl -MDevel::Peek -MList::Util=first -e'Dump(\&first)'
SV = IV(0x1094e20) at 0x1094e28
REFCNT = 1
FLAGS = (TEMP,ROK)
RV = 0x11183b0
SV = PVCV(0x10ff1f0) at 0x11183b0
REFCNT = 3
FLAGS = (POK,pPOK)
PROTOTYPE = "&@"
COMP_STASH = 0x0
XSUB = 0x7f7ecbdc61b0
XSUBANY = 0
GVGV::GV = 0x11183c8 "List::Util" :: "first"
FILE = "ListUtil.c"
DEPTH = 0
FLAGS = 0x800
OUTSIDE_SEQ = 0
PADLIST = 0x0
OUTSIDE = 0x0 (null)
那里的GVGV::GV
部分是重要的一点。
另一种解决方案是Sub::Identify
,它实际上只为您提供代码参考的名称。但是,了解Devel::Peek
在许多其他情况下也很方便,所以我首先提到了这一点。
答案 1 :(得分:10)
Perl的调试器可以挖掘你想要的方式。例如:
main::(-e:1): 0 DB<1> sub foo {} DB<2> x \&foo 0 CODE(0xca6898) -> &main::foo in (eval 5)[/usr/share/perl/5.10/perl5db.pl:638]:2-2
它使用Devel::Peek执行此操作:
=head2 C<CvGV_name_or_bust> I<coderef>
Calls L<Devel::Peek> to try to find the glob the ref lives in; returns
C<undef> if L<Devel::Peek> can't be loaded, or if C<Devel::Peek::CvGV> can't
find a glob for this ref.
Returns C<< I<package>::I<glob name> >> if the code ref is found in a glob.
=cut
sub CvGV_name_or_bust {
my $in = shift;
return unless ref $in;
$in = \&$in; # Hard reference...
eval { require Devel::Peek; 1 } or return;
my $gv = Devel::Peek::CvGV($in) or return;
*$gv{PACKAGE} . '::' . *$gv{NAME};
} ## end sub CvGV_name_or_bust
您可以使用
进行练习#! /usr/bin/perl
use warnings;
use strict;
package Foo;
sub bar {}
package main;
BEGIN { *baz = \&Foo::bar }
sub CvGV_name_or_bust { ... }
print CvGV_name_or_bust(\&baz), "\n";
输出:
Foo::bar
请注意,上面的示例为Foo:bar
提供了一个不同的名称,但是您可以获得别名子所在的包以及其名称。
答案 2 :(得分:3)
如果使用Exporter
从另一个模块自动导入该函数,可以在此模块的@EXPORT
全局变量中找到它:
perl -MEncode -e 'print join "\n", @Encode::EXPORT'
decode
decode_utf8
...
您可以向use
提供功能列表。这样,您将始终知道函数属于哪个包:
use Encode qw[ encode ]; # encode() imported from the Encode module
use Data::Dumper qw[]; # no functions imported from Data::Dumper
答案 3 :(得分:1)
您可以传递给Sub::Identify::sub_fullname
任何子例程引用,它将显示定义此子目录的模块:
use Sub::Identify qw/sub_fullname/;
sub foo {
print sub_fullname( \&foo ); # main::foo
print sub_fullname( sub{} ); # main::__ANON__
}
foo();
有关详细信息,请参阅Sub::Identify