在 OOP Perl 中调用子例程
当查看我接管的一些代码时,我遇到了这一行:
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
中的变量或子例程
。任何提示将不胜感激。我才刚刚开始学习这些东西。就像沐浴在火中一样。 (我知道以后我会更快乐)哎呀!
When looking through some code I took over, I came across this line:
my @files = My::Module::DB::raw_info->search_like(customer_handle => $config->{client}, feed => $config->{site}, arrival =>"$date")
I know that this returns an array from a package called My::Module::DB::raw_info
.
What I'm not sure of (and I am just learning OOP), is what ->search_like
refers to.
I didn't see that as a variable or as a subroutine in My::Module::DB::raw_info
Any hints would be appreciated. I'm only beginning to learn this stuff. It's like bathing in fire. (I know I'll be happier later though) Yikes!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
这可能是由于该方法是从基类继承的。然而,在极其奇怪的情况下,它也可以动态地注入到模块的名称空间中,这更难弄清楚。
您可以通过强力搜索或找出模块的基类(可能是继承链的更高层)并仅搜索基类代码来找到您的子项目。我将展示如何同时执行这两项操作:
强力搜索:在复杂情况下,这可能是最简单的解决方案,因为子组件可以通过非动态方式注入到模块的命名空间中祖先模块和查找祖先模块并不是 100% 容易,因为可以使用多种定义继承的方法(使用基础、使用父级、Moose 东西、AUTOLOADED 东西)。
首先,找出 My::Module 加载了哪些其他模块
这将打印所有这些模块的位置
然后,在所有代码中搜索子定义(以下应该都是一行,为了便于阅读,我将其分成两行):
如果返回太多结果,请更改 grep这
将在 My::Module::DB::raw_info 继承的模块中找到定义,而无需实际分析继承的模块代码。
继承:
使用
ISA
找出模块的父模块,如下所示:澄清一下,这仅适用于使用
@ISA
的“经典继承”模块,不适用于驼鹿的东西。如果使用 AutoLoader 调用例程或动态地将例程注入到符号表中,这种情况可能发生在任何代码中(不一定在父代码中),它也不起作用。This is probably due to the method being inherited from a base class. However, in the extremely weird situations, it COULD also be injected into the module's namespace dynamically which is much harder to figure out.
You can find your sub either by brute force searching or by figuring out the base class of a module (and possibly higher up the inheritance chain) and searching just the base classes code. I will show how to do both:
Brute force search: This is probably the easiest solution in complicated cases since the sub could have been injected into the module's namespace dynamically by non-ancestor module and finding ancestor modules is not 100% easy due to multiple ways of defining inheritance that could have been used (use base, use parent, Moose stuff, AUTOLOADED stuff)
First, find out which other modules are loaded with My::Module
This will print the location of ALL those modules
Then, search for the sub definition in ALL that code (the following should be all one line, I split it up for readability into 2 lines):
If this returns too many results, change the grep to
This will find you the definition in whichever module My::Module::DB::raw_info inherits from without actually analyzing the module code for inheritance.
Inheritance:
Find out the module's parent using
ISA
as follows:To clarify, this only works for "classically inherited" modules using
@ISA
, not Moose stuff. It also doesn't work if the routine is called using AutoLoader or is injected into the symbol table dynamically which can happen in any code, not necessarily in the parent one.造成您的难题的可能原因是 My::Module::DB 扩展了其他一些类。 顶部附近查找块
或
沿着My/Module/DB.pm 的顶部
编辑: 正如一些评论者在下面有用地指出的那样,有多种方法可以对 Perl 类进行子类化,但这些可能是最常见的。 (或许。)
The likely cause of your conundrum is that My::Module::DB extends some other class. Look for a block along the lines of
or
near the top of My/Module/DB.pm
Edit: As some commenters are helpfully pointing out below, there are a number of ways to subclass a Perl class, but these are probably the most common. (Maybe.)
您可以使用核心
Devel::Peek
模块来查看子例程引用中保存的内部数据。要从 OO 方法获取子例程引用,请使用所有对象的
->can(...)
方法。然后你可以打印出信息:
根据
Devel::Peek
的文档,你应该得到类似这样的内容:对子例程的引用如下所示:
表明
因此,COMP_STASH 显示了代码的编译位置,而 GVGV::GV 显示了子程序的全名。
You can use the core
Devel::Peek
module to look at the internal data held in subroutine references.To obtain a subroutine reference from an OO method, you use the
->can(...)
method of all objects.and then you can print out the information:
According to
Devel::Peek
's docs, you should get something like this:A reference to a subroutine looks like this:
This shows that
So, COMP_STASH shows you where the code was compiled, and GVGV::GV shows you the sub's full name.
该方法可以在
My::Module::DB::raw_info
的超类中定义。在调用search_like
之前插入此行:现在查看这些类。
如果这不起作用,您可以使用 Devel::Peek 的 < code>Dump() 查看子例程的来源:
在输出中查找
GVGV::GV 部分
。The method may be defined in the superclasses of
My::Module::DB::raw_info
. Insert this line before the call tosearch_like
:Now look into these classes.
If this doesn't work, you can use Devel::Peek's
Dump()
to see where the subroutine came from:Look for
GVGV::GV part
in the output.为了回答“我不确定,我刚刚学习 OOP(感谢我们的开发人员被解雇),就是“->search_like”所指的内容。”,search_like 是 raw_info 类的一种方法,将名称值对作为其输入参数(Perl Cookbook 第 10.7 节)。
仅供参考,我发现非常有用的另一本书是 Programming Perl。
In answer to "What I'm not sure of, and I am just learning OOP (thanks to our developer getting fired), is what the "->search_like" refers to.", search_like is a method of the raw_info class that takes name value pairs as its input parameters (Perl Cookbook section 10.7).
FYI, the other book I find very useful is Programming Perl.
也许这是某种继承的方法。阅读一些关于 Perl 继承 的内容,在您的文件中搜索一些对
@ISA
的赋值模块定义。Perhaps it's some inherited method. Read a little about Perl inheritance, search for some assignment to
@ISA
in your module definition.