在Perl中,我可以使用常量来促进方法调用中拼写错误的编译时间检测吗?

时间:2017-04-27 13:51:21

标签: perl

我在Perl中有以下程序:

use Class::Struct;

use constant {
    ACTION => "Action",
    TYPE => "Type"
};

struct MyClass => {           
    &ACTION => '$',
    &TYPE => '$'
};

my $obj = new MyObj{
    &ACTION => 'add',
    &TYPE => '1'
}

# compilation error:
var $action = $obj->&ACTION;

尝试使用常量访问对象字段时出现编译错误。可能吗?我做错了什么?

1 个答案:

答案 0 :(得分:6)

您的代码包含一些错误,例如当您声明的所有内容MyObj并使用MyClass而不是var时尝试实例化my。修复后,您会注意->&是语法错误。请参阅Method InvocationMethod Call Variations

您可以使用

  • 方法名称为字符串
  • 子程序引用为方法
  • 引用方法调用

那就是说,这是你的代码,带有更正,使其能够编译和运行:

use strict;
use warnings;

use Class::Struct;

use constant {
    ACTION => "Action",
    TYPE => "Type"
};

struct MyClass => {
    ACTION() => '$',
    TYPE() => '$'
};

my $obj = MyClass->new(
    ACTION() => 'add',
    TYPE() => '1'
);

print $obj->${ \ACTION };

请注意,在声明中使用ACTION()而不是&ACTION会将键转换为编译时间常量而不是运行时子例程调用(前缀为ACTION &告诉{{ 1}}忽略空原型,有效地撤消perl)的好处。

它使用Dereferencing Method Call

  

引用方法调用

     

Perl还允许您在方法调用中使用解除引用的标量引用。这是一个满口的,所以让我们看看一些代码:

use constant

上面的代码编译为 $file->${ \'save' }; $file->${ returns_scalar_ref() }; $file->${ \( returns_scalar() ) }; $file->${ returns_ref_to_sub_ref() };

像往常一样,@ikegami发现了我错过的内容:$obj->${ \'Action' }是一个运行时错误。通过使用常量作为方法名称,可以在编译时检测拼写错误。例如,如果我犯了诸如$x->doesnotexist之类的错误,编译就会失败。

在这种情况下,Const::Fast可能会提供一个美学上更令人愉悦的解决方案(即使它相对于使用常量子例程会有速度惩罚):

$obj->${ \ACITON };

输出:

C:\...\Temp> perl -c tt.pl
Global symbol "$ACION" requires explicit package name (did you forget to declare "my $ACION"?) at tt.pl line 21.
tt.pl had compilation errors.

也就是说,在编译时也会检测到这样的拼写错误。使用常量子程序会对性能造成损失,但它不那么难看。