2010-08-01 18 views
7

Tôi nghĩ rằng tiêu đề là tự giải thích. Nhiều lần tôi có lỗi chính tả nhỏ và tôi nhận được kết quả không mong muốn khi cố truy cập các khóa băm không xác định. Tôi biết tôi có thể thêm một số defined kiểm tra trước mỗi lần tôi truy cập vào một phím băm, nhưng tôi tự hỏi, nếu có bất kỳ cách nào sạch để cảnh báo chống lại những trường hợp này ....làm cho tiếng kêu rầm rộ khi cố gắng truy cập vào khóa băm không xác định

nhất, Dave

+1

Bạn không có ý định kiểm tra xem khóa có được 'định nghĩa' hay không, nhưng liệu nó có tồn tại hay không. Không có các khóa băm không xác định * mỗi lần *. – pilcrow

+0

@pilcrow cảm ơn sự điều chỉnh. –

Trả lời

14

Đây có lẽ là tốt nhất thực hiện với một băm trói. Các biến gắn kết cho phép bạn xác định việc thực hiện các hoạt động ở mức độ thấp của biến. Trong trường hợp này, chúng tôi muốn có một phương pháp lấy đặc biệt mà chết khi truy cập vào các phím không tồn tại:

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 

trong việc thực hiện các Safe::Hash trên, đầu tiên tôi tải Tie::Hash cung cấp Tie::StdHash. Đặt @ISA thành Tie::StdHash cung cấp gói mới của chúng tôi với các phương thức tie hoạt động theo cách tương tự như băm thông thường. Mỗi phương pháp liên kết được nêu trên http://perldoc.perl.org/perltie.html

Trong trường hợp này, phương pháp duy nhất để ghi đè là FETCH được chuyển qua tham chiếu đến đối tượng được gắn ẩn (trường hợp này là hashref) và khóa để sử dụng. Nó sẽ kiểm tra xem vị trí đó có tồn tại hay không và trả về lỗi hoặc ném một lỗi

+0

rất tuyệt! bạn có thể giải thích phần FETCH không? đây là một từ dành riêng? –

+0

Biến cố định cung cấp một tập hợp các phương thức để bạn ghi đè cho phép bạn chỉ định hành vi của chúng. Xem perltie cho tất cả các chi tiết: http://perldoc.perl.org/perltie.html – friedo

7

Sử dụng Hash :: util:

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

đầu ra:

42 
Attempt to access disallowed key 'baz' in a restricted hash at foo line 5. 

có chức năng khác cho phép đó nêu rõ các phím cho phép, không chỉ mặc định cho wha t đã có.

+0

Cảm ơn bạn, điều này là tốt đẹp, nhưng tôi tự hỏi nếu có cái gì đó tốt hơn phù hợp với nhu cầu của tôi. Tôi muốn một lỗi được tạo ra bất cứ khi nào tôi cố gắng truy cập một khóa không xác định, trừ khi truy cập là một nhiệm vụ. Hàm băm của tôi là động - tôi thêm khóa và nhận khóa mọi lúc - vì vậy hãy sử dụng Hash :: Util sẽ làm cho tôi khóa và mở khóa liên tục và tôi cũng có thể kiểm tra xem khóa có được xác định hay không. –

+0

@ David B: sau đó bạn có thể muốn sử dụng một băm gắn, như Eric Strom gợi ý. Mặc dù tôi tự hỏi chính xác bạn đang làm gì với các giá trị bạn nhận được? Nhiều hoạt động nên đã được cảnh báo về giá trị không xác định, giả sử bạn đã bật cảnh báo. – ysth

4

Bạn có thể viết một hàm đơn giản cho việc này:

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

my %hash = (...);  
my $val = get(\%hash, "mykey"); 
Các vấn đề liên quan