首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Perl中禁用自动生动?

如何在Perl中禁用自动生动?
EN

Stack Overflow用户
提问于 2009-04-26 09:00:27
回答 5查看 5K关注 0票数 8

假设您有一个大型应用程序"develoopped“;)由一个大团队开发。这里是一个简化的模型,当某人检查数据结构太深时,可能会发生潜在的灾难。如果不能完全或在范围内禁用自动虚拟化,如何解决此问题?非常感谢:)!

代码语言:javascript
复制
use strict; use warnings;use Data::Dumper;

my $some_ref = {akey=>{deeper=>1}};
print Dumper($some_ref );
if($some_ref->{deep}{doot} == 1){
    print 'too deep '.$/;
}

if($some_ref->{deep}){
    print 'Already in a deep doot'.$/;
}

print Dumper($some_ref );

这将输出以下内容:

代码语言:javascript
复制
$VAR1 = {
          'akey' => {
                      'deeper' => 1
                    }
        };
Use of uninitialized value in numeric eq (==) at autovivify_test.pl line 5.
Already in a deep doot
$VAR1 = {
          'deep' => {},
          'akey' => {
                      'deeper' => 1
                    }
        };

是的,我知道这是个警告,但是...现在可能已经太晚了。

可以这样说,我的hashref引用了一个绑定的散列。

也许如果我实现一个好的FETCH方法,在结构中更深层次地检查检查,我会很容易解决我的问题?

我研究了Tie::StrictHashTie::Hashperltie。以下是我的解决方案的简化版本:

代码语言:javascript
复制
#!/usr/bin/env perl;
#test_tie.pl

package StrictHash;
use strict; use warnings;
use Tie::Hash;
our @ISA = qw(Tie::StdHash);
use Carp;

sub TIEHASH {
    my $class = shift;
    my $hash = bless {@_}, $class;
    return $hash;
}
##========================================================================
## FETCH fails if applied to a member that doesn't exist.
##========================================================================
sub FETCH {
    my ($hash, $key) = @_;
    Carp::confess "key '$key' does not exist" unless exists $hash->{$key};
    return $hash->{$key};
}
##========================================================================
package main;
use strict;use warnings;use Data::Dumper;
#Imagine StrictHash is in ./StrictHash.pm
#use StrictHash;
my %hash;
tie %hash, 'StrictHash', akey => {deeper=>1} ;  

my $some_ref =\%hash;
print Dumper($some_ref );
if($some_ref->{deep}{doot} == 1){
    print 'too deep '.$/;
}

我实现的是只触摸应用程序中的一个地方。现在,所有像if($some_ref->{deep}{doot})这样的地方都会导致堆栈跟踪。因此,我会很容易地找到它们并纠正它们。而这种新的写作将是不可能的。Perl也适用于大型应用程序,您只需了解更多;)。

谢谢大家!我希望这对其他人也有帮助。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2009-04-26 09:29:42

您可能希望使用对象而不是散列(请参阅Moose)或使用strict tied hash。或者,您可以将警告转换为错误,如果您确实想这样做的话:

代码语言:javascript
复制
use warnings NONFATAL => 'all', FATAL => 'uninitialized';
票数 16
EN

Stack Overflow用户

发布于 2009-07-10 13:24:44

相对较新的是autovivification模块,它允许您执行以下操作:

代码语言:javascript
复制
no autovivification;

非常简单。

票数 22
EN

Stack Overflow用户

发布于 2009-04-26 10:22:02

您可以使用Hash::Util中的一个函数(一个核心模块)来锁定散列。

代码语言:javascript
复制
use Hash::Util qw( lock_keys unlock_keys );

my $some_ref = { akey => { deeper => 1 } };
lock_keys %$some_ref;

print "too deep" if $some_ref->{deep}{shit} == 1;

现在最后一条语句将抛出一个异常:

代码语言:javascript
复制
Attempt to access disallowed key 'deep' in a restricted hash

当然,缺点是在检查散列中的键时必须非常小心,以避免异常,例如,在访问键之前使用lof "if exists ...“来检查键。

如果您稍后需要再次向散列中添加密钥,可以解锁它:

代码语言:javascript
复制
unlock_keys %$some_ref;
$some_ref->{foo} = 'bar'; # no exception
票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/790516

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档