在Perl中,如何检查导入给定函数的模块?

Nik*_*ita 20 perl module function subroutine

我有一个调用该函数的代码.但我不知道这个功能属于哪个模块.我需要它来修改这个功能.

我怎么检查呢?

raf*_*afl 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)
Run Code Online (Sandbox Code Playgroud)

GVGV::GV那里的部分是重要的一点.

An alternative solution would be Sub::Identify, which really only gives you names for code references you hand to it. However, knowing about Devel::Peek is handy in many other situations too, so I mentioned that first.

  • 这比我本来要好得多.在使用每个模块之后,我会在`()`处添加,直到代码编译失败. (4认同)

Gre*_*con 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
Run Code Online (Sandbox Code Playgroud)

你可以锻炼它

#! /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";
Run Code Online (Sandbox Code Playgroud)

输出:

Foo::bar

请注意,上面的示例给出Foo:bar了不同的名称,但是您可以获得别名子所在的包以及其名称.


Eug*_*ash 3

如果该函数是使用 从另一个模块自动导入的,则可以在该模块的全局变量 Exporter中找到它:@EXPORT

perl -MEncode -e 'print join "\n", @Encode::EXPORT'
decode   
decode_utf8
...   
Run Code Online (Sandbox Code Playgroud)

您可以向 提供函数列表use。这样你就总能知道函数属于哪个包:

use Encode       qw[ encode ]; # encode() imported from the Encode module
use Data::Dumper qw[];         # no functions imported from Data::Dumper
Run Code Online (Sandbox Code Playgroud)