Non è necessario controllare ogni livello dell'eradarchia: si può semplicemente andare per il valore che ti interessa. exists
non verifica la definizione, solo se lo slot dell'hash esiste (potrebbe esistere con un valore non definito), quindi se si cura che il valore sia definito, è necessario chiamare defined
anziché esistente. Se un valore non è definito, si valuta in contesto booleano false, in modo da poter digitare un po 'meno e ridurre il vostro esempio a:
if ($Table{$key1}{$key2})
{
# do whatever
}
Tuttavia, se il valore di quella chiave è definito, ma è "falsa" (valuta numerico a zero, o è una stringa vuota), questo può causare un falso negativo, quindi dovremmo esplicitamente controllare definedness se questa è una possibilità:
if (defined $Table{$key1}{$key2})
{
# do whatever
}
Se non si desidera autovivify $Table{$key1}
, è possibile verificare la sua esistenza prima, che ci porta al modo "migliore" per il caso generale:
if (exists $Table{$key1} and defined $Table{$key1}{$key2})
{
# do whatever
}
Se avete intenzione di fare questo molto per vari campi in un hash, si consiglia di aggiungere alcuni metodi di accesso OO stile che fare questo lavoro per voi:
sub has_field
{
my ($this, $fieldName) = @_;
return exists $this->{data} && defined $this->{data}{$fieldName});
}
sono sicuro che avete letto già, ma non può far male a leggere di nuovo la relativa documentazione:
Data un'espressione che specifica un elemento di un hash o elemento di matrice, exists
restituisce vero se l'elemento specificato nella hash o array è mai stato inizializzato, anche se il valore corrispondente è non definito. L'elemento non viene autovivificato se non esiste.
...
Un elemento di hash o di matrice può essere vero solo se è definito e definito se esiste, ma il contrario non è necessariamente valido.
Modifica la domanda per utilizzare i blocchi di codice per il codice. – justkt