假设您有一个由大团队“开发”的巨大应用程序。 以下是可能发生的潜在灾难的简化模型,当有人在数据结构中进行深入检查时。 如果无法完全禁用自动验证或作用域内的自动验证,该如何解决? 非常感谢 :) !!!!
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 );
这将输出以下内容:
$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
}
};
是的,我知道有一个警告,但是...可能为时已晚。
需要说明的是,我的哈希引用了一个绑定的HASH。
也许如果我实现一个良好的FETCH方法来检查更深层次的结构,我可以轻松地解决我的问题?
我查看了Tie::StrictHash,Tie::Hash和perltie。这是我解决方案的简化版本:
#!/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也适用于大型应用程序,你只需要了解更多 ;). 谢谢大家! 希望这对其他人也有所帮助。