如何检测“严格”'模块内的pragma?

时间:2014-08-15 04:48:00

标签: perl perl-module

通常,当我在Perl中构建数据结构时,我最终必须将其从%leaf声明为%root,所以我一直在修改一个模块,允许我从<登记/> $seed$seed->trunk->branch->leaf

使用AUTOLOADnew子例程并不困难。我对SO的问题是如何检测'严格'编译指示是否正在使用,以便模块以不同的模式运行,这需要在使用之前“声明”变量,因此我不会意外地为$seed->drunk当我使用strict时 - 假设模块被称为branch,这是模块使用的有效语法

$seed->declare('trunk');
$seed->trunk(new branch);

$seed->trunk->declare('leaf');
$seed->trunk->leaf("value");

如何在模块的调用程序中检测严格编译指示是否有效?

可能这是不可能的 - 在这种情况下,我必须使用静态变量来处理与模块无关的编译指示。

EDITED / POSTSCRIPT:

我编写了初始版本,没有检查'严格'或实现'declare'子例程,并意识到如果自动加载器通过引用操作,它将不会提供足够简单的用户语法,所以我写了它来检查对于第一个参数并分配传递给对象引用的哈希表中的元素的值,否则如果没有参数则返回指定元素的值。

所以我发布了分支模块的代码以满足您的好奇心。请注意,我还没有实施严格检查。

package branch;

sub new
{
    my $type = shift;
    my $self = { };
    bless $self, $type;
    return $self;
}

sub DESTROY
{
    my $self = shift;
    %$self = undef;
}

sub AUTOLOAD
{
    my $self = shift;
    my $value = shift;

    my $sub = $AUTOLOAD;
    my ($type, $PROGRAM) = ($sub =~ /(.*)::(.*)/);

    if( $value ne undef )
    {
        $$self{$PROGRAM} = $value;
        return $value;
    }
    return $$self{$PROGRAM};
}

1;

2 个答案:

答案 0 :(得分:6)

那么第一件事就是,严格什么? Strict有三个subpragma,有自己的行为和要检查的位。 use strict 'refs'不允许您取消引用字符串; use strict 'vars'不允许您以不合格的方式访问全局变量,而use strict 'subs'会在少数情况下禁用裸字。 use strict等同于所有三个,但它们中没有一个真正看起来足够接近你要求捎带的东西。

所以直接回答你的问题:[8]返回的列表中的元素caller($i)返回对$i级别调用者有效的编译提示位。如果查看strict.pm,您可以看到每个子ppmama设置的位,并在调用者级别检查它们,这些代码与实际调用方法的代码相对应。

但是,回到我原来的观点,你可能不应该这样做,因为那不是严格意义上的。您应该接受对象的选项&#39;构造函数决定它们是否应该严格表现,或者如果你确实想要一个词汇编纂而不是跟随你的对象的东西,你应该使用perlpragma中的信息编写自己的一个教程。自5.10以来的所有perls都支持使用%^H提示哈希值的任意用户定义编译指示,该哈希值作为调用者信息的元素[10]公开。

答案 1 :(得分:2)

你似乎对严格的pragma的范围感到困惑。

如果模块使用strict,则不会对模块的用户强制执行任何操作。即使你想扩展包,也可以通过子类化或猴子修补来扩展其他方法。

use strict仅适用于其中使用的文件。 (或者,如果它在一对花括号中使用,它只适用于结束括号。)因此,如果你正在扩展一个包,只需在一个单独的文件中进行,而没有一个pragma应用于原始模块将适用于您的代码。


也就是说, use strict很少有好主意。偶尔的任务可能会在一个小范围内禁用它,但你所描述的问题似乎并不是其中之一。

特别是,如果您要构建一个深层嵌套的结构,则不需要声明每个级别。示范:

use strict;
use warnings;
use Data::Dumper;

my $root;
$root->{trunk}{branch}{leaf} = 42;

print Dumper($root);