如何找到我正在 Perl 中处理的对象类型? 我尝试使用 perl -d 进入调试器,但我不知道接下来该怎么做。 同样,我想要一种方法来轻松查看每个对象可以使用哪些方法,如何才能做到这一点?
ref
或 Scalar::Util
::blessed
。如果您知道该对象受到祝福,那么它们会返回相同的信息。
my $class1 = blessed( $obj );
my $class2 = ref $obj;
但是
ref
也会为未受祝福的哈希值返回“HASH”,而 blessed
拒绝玩该游戏。
至于方法列表,对于 Perl 对象受祝福的指针样式,您自己编写一个方法很容易。下面的代码对我来说效果很好。它返回映射到定义它们的包的函数名称(那些采用给定名称的“代码槽”的函数)。
sub class_methods {
use Class::ISA;
my $obj = shift;
return unless ref( $obj );
my %meth_names;
foreach my $anc ( Class::ISA::self_and_super_path( ref $obj ), 'UNIVERSAL' ) {
my $stash = \%{"$anc\::"};
my @funcs
= grep { m/^[_\p{Alpha}]/ # begins with _ or alpha
&& !exists $meth_names{$_} # no clobbering
&& defined *{$stash->{$_}}{CODE} # has a filled CODE slot
} keys %$stash
;
# assign to the "hash slice", keyed by all the entries in @funcs
# the value of $anc repeated as many times as elements in @funcs.
@meth_names{@funcs} = ( $anc ) x @funcs;
}
return %meth_names;
}
这也适用于相当复杂的对象,但是如果所属包包含大量生成的代码,那么了解生成器将代码指针插入哪个包就没有多大帮助了。这将意味着更多的查找什么包生成了代码。
Data::Dumper
并将$Data::Dumper::Deparse
设置为1,如下所示:(local $Data::Dumper::Deparse = 1;
)然后转储代码指针,例如所以:say Dumper( $code_ref );
它WON'T适用于尚未由任何
AUTOLOAD
方法创建的有效方法。如果您在列表中看到这些内容,则该对象可能会执行更多操作,但您不知道它做了什么。包含“基类”
UNIVERSAL
,因为该类包含对象可用的行为。 祝你好运。
来自 Scalar::Util
的
blessed
函数将告诉您任何受祝福的引用(对象)的包名称。
要了解可用的方法,请查阅该包的文档。或者,您可以使用类似 Class::MOP::Class 来实例化元类并获取有关它包含的方法的内省信息。
为了完整起见,这里有一个关于调试器的简短介绍。
perl -d your_program
在 bugger 下启动它。您将在第一个可执行行获得控制(use 语句等已在此时执行)。
's' 将进入下一行。输入“s”后,只需按回车键即可重复输入。 's' 将逐步进入函数/子例程/方法。要么继续单步执行直到返回,要么输入“r”命令来执行函数的其余部分并在调用后立即返回。
如果您想“跳过”子例程 - 即执行它们并返回,而不必介入并返回,请使用“n”。第一个“n”之后的回车也会继续为您做“n”。
如果您知道要停止的行,请使用“b”命令 - b 行号 - 设置断点,然后使用“c”继续,直到到达它。请注意,每次您“c”并返回到断点时,您都会再次停止。使用“B linenumber”关闭断点。
所以我们假设你已经得到了这样的结果:
my $obj = complex_function_returning_unknown_thing;
调试器刚刚向您显示了这一行,其中表示“我还没有执行此操作,但这是我下一步要做的。”输入“n”执行子例程,然后使用“x”命令查看对象:“x $obj”。如果它很大,您可以说“|x $obj”,它通过寻呼机运行输出。要查看对象有哪些方法,请使用“m $obj”。
调试器还有很多功能,但您确实可以将它用于此类事情 - 您只需查看从某些代码中获取的对象的类型,并找出您获取的对象具有哪些方法。
“x”该对象可能更有用,然后查看该对象被祝福的类的源代码,以找出您“应该”做什么,而不是“可以”做什么。无论如何,“x”命令几乎是“print ref($obj)”与 Data::Dumper 的交叉。 您正在寻找 Perl 中的反射。我刚刚用谷歌搜索了不带引号的“Perl Reflection”,结果出现了: