如何查找此行引用的Perl代码?

时间:2017-09-29 22:51:33

标签: perl

我继承了一些Perl代码,其中包含一条对我来说神秘的行:

my $binary = A->current->config->settings('arg1', 'arg2')

基本上,我不知道如何找到相关代码。 “A”不是本地代码中的变量,所以我认为这是一个类层次结构。但是我检查了目录结构以查看是否存在以下路径,但是没有:

A/current/config/settings.pm

A->current->config->settings是否保证是嵌套的类层次结构,还是可能是其他的?例如,config实际上可以是不同对象的属性或方法A->current

任何你可以帮助追踪这一点的帮助都将非常感谢!

4 个答案:

答案 0 :(得分:2)

A是一个类名,您应该在A.pm中找到它。 current应该是类的方法,在sub current中的A.pm下定义。它返回一个正在调用config方法的对象,该对象再次返回一个对象,其settings方法正在使用参数'arg1''arg2'调用(实际上,对象是本身就是第一个论点。)

实际上,任何方法都可以返回一个类而不是一个对象。

答案 1 :(得分:2)

逐步查看perl debugger中的代码,了解它的用途。

foo->bar是一个方法调用,这意味着在bar(或超类)引用的包中可能会定义一个名为foo的子例程,并且不会为您提供任何信息。是否有包barfoo::bar

答案 2 :(得分:2)

  

A->current->config->settings保证是嵌套的类层次结构

您正在考虑A::current::config::settings

以下是方法调用:

INVOCANT->name
INVOCANT->name(LIST)

这意味着A->current->config->settings是一系列方法调用。

该代码中唯一命名的类是A

  

config实际上可以是不同对象A->current的属性或方法吗?

它是A->current返回的对象或类的方法的名称。

  

如何查找此行引用的Perl代码?

my $binary = A->current->config->settings('arg1', 'arg2');

的缩写
my $obj1   = A->current;
my $obj2   = $obj1->config;
my $binary = $obj2->settings('arg1', 'arg2');

现在你有了可用的对象,你可以使用

找到它们是一个实例的类
say ref($obj) || "Not a reference";

use Scalar::Util qw( blessed );

say blessed($obj) // "Not an object";

答案 3 :(得分:1)

如上所述,您正在处理名为AudioManager am = (AudioManager) getSystemService(AUDIO_SERVICE); int volume_level1= am.getStreamVolume(AudioManager.STREAM_RING); int maxVolume=am.getStreamMaxVolume(AudioManager.STREAM_RING); final MediaPlayer mp1 = MediaPlayer.create(context, R.raw.notification_delivery); mp1.setAudioStreamType(AudioManager.STREAM_MUSIC); float log1=(float)(1-Math.log(maxVolume-volume_level1)/Math.log(maxVolume)); mp1.setVolume(log1,log1); 的类中的一系列方法调用,其中至少第一个是class method,因为它是在类上调用的(A })本身,而不是对象。

以下是使用Class::Inspector

查找该课程的第一种简便方法
A

打印了我在测试中使用的类的完整路径。另请参阅use Class::Inspector; say "Filename: ", Class::Inspector->resolved_filename( 'A' );

询问的一种方法:创建loaded_filename的对象并在运行时向其添加方法

A

这些是简单的示例,但您几乎可以从方法内部获取任何信息。

如果my $objA = A->new(); eval q( sub A::get_info { print "$_\n" for (caller(0)) } ); if ($@) { print "Eval: $@" }; eval q( sub A::boom { croak "Stacktrace: " } ); if ($@) { print "Eval: $@" }; $objA->get_info(); $objA->boom(); 碰巧没有名为A的方法(可能)使用给定链中的方法,则从new开始。

或者,您可以直接将子例程添加到包的符号表

my $objA = A->current

现在也可用于所有现有实例以及新实例。