2010-08-01 35 views
7

erişmeye çalışırken perl shout yapmak başlık kendisinin açıklayıcı olduğunu düşünüyorum. Çoğu zaman küçük yazım hatalarım var ve undefined hash anahtarlarına erişmeye çalışırken beklenmedik sonuçlar elde ediyorum. ::undefined hash key

iyisi, Dave

+1

Bir anahtarın "tanımlı" olup olmadığını değil, "var" olup olmadığını kontrol etmek istemezsiniz. * Tanımlanmamış hash tuşları yoktur *. – pilcrow

+0

@pilcrow düzeltme için teşekkürler. –

cevap

14

Bu muhtemelen en iyi bir bağladılar karma ile yapılır. Bağlı değişkenler, değişkenin düşük seviyeli işlemlerinin uygulanmasını tanımlamanıza izin verir. İlk yük Tie::StdHash sağlar Tie::Hash, yukarıda

use warnings; 
use strict; 

{package Safe::Hash; 
     require Tie::Hash; 
     our @ISA = 'Tie::StdHash'; 
     use Carp; 

     sub FETCH { 
       exists $_[0]{$_[1]} or croak "no key $_[1]"; 
       $_[0]{$_[1]} 
     } 
} 

tie my %safe => 'Safe::Hash'; 

$safe{a} = 5; # ok 

print $safe{a}, "\n"; # ok 

$safe{b} = 10; # ok 

print $safe{bb}, "\n"; # dies 

Safe::Hash uygulanmasında; bu durumda, biz var olmayan anahtarlar erişirken ölür özel getirme yöntemi istiyorum. @ISA - Tie::StdHash ayarı, yeni paketimizi normal karılarla aynı şekilde davranan bağlama yöntemleri sağlar. Bağ yöntemlerinin her biri http://perldoc.perl.org/perltie.html

'da özetlenmiştir. Bu durumda, geçersiz kılmanın tek yöntemi, gizli bağlı nesneye (bu durumda bir hashref) bir başvuru geçirilen ve kullanılacak anahtar olan FETCH'dur. Yuvanın var olup olmadığını kontrol eder ve ya döndürür ya da bir hata atar

+0

çok havalı! lütfen FETCH bölümünü açıklar mısınız? bu ayrılmış bir kelime mi? –

+0

Bağlı değişkenler, davranışlarını belirtmenize izin veren geçersiz kılmanız için bir yöntem kümesi sağlar. Tüm ayrıntılar için perltie bakın: http://perldoc.perl.org/perltie.html – friedo

7

Kullanım Hash .... ben bir kare tuşuna erişmek her zaman önce bazı defined çek ekleyebilir biliyorum ama bu gibi durumlarda karşı uyarmak için herhangi temizleyici yolu var mı acaba util:

use Hash::Util "lock_keys"; 
my %hash = (foo => 42, bar => 23); 
lock_keys(%hash); 
print $hash{foo}; 
print $hash{baz}; 
print $hash{bar}; 

çıkışı:

tuşları sadece wha varsaymak değil, izin belirterek izin diğer işlevleri vardır
42 
Attempt to access disallowed key 'baz' in a restricted hash at foo line 5. 

Orada zaten var.

+0

Teşekkür ederim, bu güzel, ama merak ediyorum ki ihtiyaçlarım için daha uygun bir şey var mı. Erişim bir ödev olmadıkça, tanımlanmamış bir anahtara erişmeye çalıştığımda bir hata oluşmasını isterim. Benim hash dinamiktir - Anahtarlar ekleyip anahtarları her zaman aldım - böylece Hash :: Util kullanarak beni sürekli kilitler ve kilidini açar ve anahtarın tanımlanıp tanınmadığını kontrol edebilirim. –

+0

@David B: o zaman muhtemelen Eric Strom'un önerdiği gibi bağlı bir karma kullanmak istersiniz. Aldığınız değerler ile tam olarak ne yaptığınızı merak ediyorum? Uyarıların etkinleştirildiğini varsayarak, birçok işlem tanımlanmamış değerler hakkında zaten uyarı vermelidir. – ysth

4

Bunun için basit bir fonksiyon yazabiliriz:

sub get { 
    my ($hash, $key) = @_; 
    die "No such key: $key" unless exists $hash->{$key}; 
    return $hash->{$key}; 
} 

my %hash = (...);  
my $val = get(\%hash, "mykey");