¿Cómo desactivo la autovivificación en Perl?
Suponga que tiene una ENORME aplicación "desarrollada";) por un gran equipo. Aquí hay un modelo simplificado del posible desastre que puede ocurrir cuando alguien verifica demasiado en una estructura de datos. Si no es posible deshabilitar la autovificación por completo o dentro del alcance, ¿cómo solucionar esto? Muchas gracias :) !!!
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 );
Esto genera lo siguiente:
$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
}
};
Sí, sé que hay una advertencia, pero ... puede ser demasiado tarde.
Hola chicos, puede ser útil decir que mi hashref hace referencia a un HASH vinculado.
Puede ser que si implemento un buen método FETCH que verifica los controles más profundos en la estructura, resolveré fácilmente mi problema?
MiréTie :: StrictHash,Tie :: Hash y perltie. Aquí está la versión simplificada de mi solución:
#!/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 '.$/;
}
Lo que logré es tocar solo un lugar en la aplicación. Ahora, todos los lugares como if ($ some_ref -> {deep} {doot}) causarán la muerte con stack-trace. Así que los encontraré y corregiré fácilmente. Y nuevos escritos de este tipo NO serán posibles. Perl también es bueno para aplicaciones grandes, solo necesitas saber más;).
¡Gracias a todos! Espero que esto ayude a otros también.