在OOP Perl中调用子例程

时间:2010-10-27 14:48:26

标签: perl oop package perl-module

在查看我接手的一些代码时,我遇到了这一行:

 my @files = My::Module::DB::raw_info->search_like(customer_handle => $config->{client}, feed => $config->{site}, arrival =>"$date")

我知道这会从名为My::Module::DB::raw_info的包中返回一个数组。

我不确定(我只是学习OOP),是->search_like所指的。

我没有在My::Module::DB::raw_info

中看到它作为变量或子程序

任何提示都将不胜感激。我才开始学习这些东西。这就像在火中沐浴。 (我知道我以后会更高兴)Yikes!

6 个答案:

答案 0 :(得分:8)

这可能是由于该方法是从基类继承而来的。然而,在非常奇怪的情况下,它也可以动态地注入到模块的命名空间中,这很难弄清楚。

您可以通过强力搜索或通过计算模块的基类(可能更高的继承链)并仅搜索基类代码来查找子。我将展示如何做到这两点:


暴力搜索:在复杂的情况下,这可能是最简单的解决方案,因为sub可能已被非祖先模块动态注入模块的命名空间并找到祖先由于可以使用多种定义继承的方法(使用base,使用parent,Moose stuff,AUTOLOADED stuff),模块不是100%容易的。

首先,找出哪些其他模块加载了My :: Module

perl -e 'use My::Module::DB::raw_info; print "$INC{$_}\n" foreach keys %INC'

这将打印所有这些模块的位置

然后,在所有代码中搜索子定义(以下应该是所有一行,我将其拆分为可读性为2行):

grep search_like 
   `perl -e 'use My::Module::DB::raw_info; print "$INC{$_}\n" foreach keys %INC'`

如果返回太多结果,请将grep更改为

grep "sub search_like"
   `perl -e 'use My::Module::DB::raw_info; print "$INC{$_}\n" foreach keys %INC'`

这将在My :: Module :: DB :: raw_info继承的模块中找到你的定义,而不实际分析继承的模块代码。


<强>继承

使用ISA查找模块的父级,如下所示:

perl -e 'use My::Module::DB::raw_info; print "@My::Module::DB::raw_info::ISA\n";'

为了澄清,这仅适用于使用@ISA的“经典继承”模块,而不适用于Moose的东西。如果使用AutoLoader调用例程或者动态注入到符号表中它也不起作用,这可能发生在任何代码中,不一定在父代码中。

答案 1 :(得分:5)

你的难题的可能原因是My :: Module :: DB扩展了其他一些类。按照

的方式寻找一个区块
use parent Some::Module;

BEGIN { extends Some::Module }

靠近My / Module / DB.pm

的顶部

编辑:正如一些评论者在下面有帮助指出的那样,有很多方法可以将Perl类子类化,但这些方法可能是最常见的。 (也许。)

答案 2 :(得分:2)

您可以使用核心Devel::Peek模块查看子例程引用中保存的内部数据。

要从OO方法获取子例程引用,请使用所有对象的->can(...)方法。

my $code_ref = My::Module::DB::raw_info->can('search_like');

然后你可以打印出信息:

use Devel::Peek 'Dump';

Dump($code_ref);

根据Devel::Peek的文档,你应该得到这样的东西:

对子程序的引用如下所示:

    SV = RV(0x798ec)
      REFCNT = 1
      FLAGS = (TEMP,ROK)
      RV = 0x1d453c
    SV = PVCV(0x1c768c)
      REFCNT = 2
      FLAGS = ()
      IV = 0
      NV = 0
      COMP_STASH = 0x31068  "main"
      START = 0xb20e0
      ROOT = 0xbece0
      XSUB = 0x0
      XSUBANY = 0
      GVGV::GV = 0x1d44e8   "MY" :: "top_targets"
      FILE = "(eval 5)"
      DEPTH = 0
      PADLIST = 0x1c9338

这表明

  • 子程序不是XSUB(因为START和ROOT非零,XSUB为零);
  • 它是在包main中编译的;
  • 名称为MY :: top_targets;
  • 在程序的第5个评估区内;
  • 目前尚未执行(请参阅DEPTH);
  • 它没有原型(缺少PROTOTYPE字段)。

因此,COMP_STASH显示代码编译的位置,GVGV :: GV显示子的全名。

答案 3 :(得分:1)

该方法可以在My::Module::DB::raw_info的超类中定义。在致电search_like之前插入此行:

print @My::Module::DB::raw_info::ISA;

现在看看这些课程。

如果这不起作用,您可以使用Devel::PeekDump()来查看子例程的来源:

use Devel::Peek;
Dump(\&search_like);

在输出中查找GVGV::GV part

答案 4 :(得分:1)

也许这是一些继承的方法。阅读一些关于Perl inheritance的内容,在模块定义中搜索@ISA的某些作业。

答案 5 :(得分:1)

在回答“我不确定,我只是在学习OOP(感谢我们的开发人员被解雇)”时,“ - &gt; search_like”指的是什么。“,search_like是一种方法raw_info类,它将名称值对作为其输入参数(Perl Cookbook section 10.7)。

仅供参考,我觉得非常有用的另一本书是Programming Perl