2009-02-18 38 views
7

Tôi đang gửi một chương trình con một băm và tìm nạp nó bằng my($arg_ref) = @_;

Nhưng chính xác thì %$arg_ref là gì? Là %$ dereferencing hash?

Trả lời

17

$arg_ref là vô hướng vì nó sử dụng $ sigil. Có lẽ, nó giữ một tham chiếu băm. Vì vậy, có, %$arg_ref suy luận rằng tham chiếu băm. Một cách khác để viết nó là %{$arg_ref}. Điều này làm cho ý định của mã một chút rõ ràng hơn, mặc dù tiết hơn.

Để trích dẫn từ perldata(1):

Scalar values are always named with '$', even when referring 
to a scalar that is part of an array or a hash. The '$' 
symbol works semantically like the English word "the" in 
that it indicates a single value is expected. 

    $days    # the simple scalar value "days" 
    $days[28]   # the 29th element of array @days 
    $days{'Feb'}  # the 'Feb' value from hash %days 
    $#days    # the last index of array @days 

Vì vậy, ví dụ bạn sẽ là:

 %$arg_ref   # hash dereferenced from the value "arg_ref" 

my($arg_ref) = @_; lấy mục đầu tiên trong ngăn xếp luận và đặt nó vào một biến địa phương gọi là $arg_ref của hàm. Người gọi có trách nhiệm chuyển một tham chiếu băm. Một cách kinh điển hơn để viết đó là:

my $arg_ref = shift; 

Để tạo một tham chiếu băm bạn có thể bắt đầu với một băm:

some_sub(\%hash); 

Hoặc bạn có thể tạo ra nó với một tham chiếu băm vô danh:

some_sub({pi => 3.14, C => 4}); # Pi is a gross approximation. 
+0

Tạo mẫu có thể được sử dụng để xóa trách nhiệm chuyển tài liệu tham chiếu khỏi người gọi. – chaos

+0

Tôi không nghĩ rằng việc tạo mẫu cho các lập trình viên Perl mới là một ý tưởng hay. Đó là một rào cản lớn đến từ C và Pascal. Tôi cần phải tìm hiểu giá trị thực sự của danh sách đi qua trước khi nguyên mẫu có ý nghĩa với tôi. Nó có thể là tiện dụng ở đây, tuy nhiên. –

+1

$ sigil không có nghĩa là biến vô hướng. Nó có nghĩa là một giá trị * vô hướng *, như trong $ hash {key} và $ array [$ num]. Trong trường hợp này, nó là một biến vô hướng vì nó là một giá trị vô hướng và không có ký tự lập chỉ mục sau nó. –

7

Thay vì dereferencing toàn bộ băm như vậy, bạn có thể lấy các mục riêng lẻ với

$arg_ref->{key} 
4

Giới thiệu ngắn gọn về tài liệu tham khảo (tạo và sử dụng chúng) trong Perl là perldoc perfeftut. Bạn cũng có thể read it online (hoặc tải xuống dưới dạng pdf). (Nó nói nhiều hơn về các tham chiếu trong các cấu trúc dữ liệu phức tạp hơn là về việc chuyển vào và ra khỏi các chương trình con, nhưng cú pháp là như nhau.)

1

Vì nó có phần rõ ràng, cấu trúc này đang được sử dụng để cung cấp tham chiếu băm các đối số được ghi tên vào một phụ nó cũng cần lưu ý rằng đây

sub foo { 
    my ($arg_ref) = @_; 
    # do something with $arg_ref->{keys} 
} 

có thể overkill như trái ngược với chỉ giải nén @_

sub bar { 
    my ($a, $b, $c) = @_; 
    return $c/($a * $b); 
} 

Tùy thuộc vào độ phức tạp danh sách đối số là.

2
my %hash = (fred => 'wilma', 
      barney => 'betty'); 
my $hashref = \%hash; 
my $freds_wife = $hashref->{fred}; 
my %hash_copy = %$hash # or %{$hash} as noted above. 

Soo, điểm linh hoạt của cú pháp là gì?Hãy thử điều này:

my %flintstones = (fred => { wife => 'wilma', 
           kids => ['pebbles'], 
           pets => ['dino'], 
          } 
        barney => { # etc ... } 
       ); 

Trên thực tế cho các cấu trúc dữ liệu sâu như thế này nó thường thuận tiện hơn để bắt đầu với một ref:

my $flintstones = { fred => { wife => 'Wilma', 
           kids => ['Pebbles'], 
           pets => ['Dino'], 
           }, 
        }; 

OK, vì vậy fred được một con vật cưng mới, 'Velociraptor'

push @{$flintstones->{fred}->{pets}}, 'Velociraptor'; 

Fred có bao nhiêu vật nuôi?

vô hướng @ {Flintstones -> {fred} -> {}} vật nuôi

Hãy cho chúng ăn ...

for my $pet (@ {flintstones->{fred}->{pets} }) { 
    feed($pet) 
} 

và vân vân. Các món súp khung xoăn có thể nhìn một chút khó khăn lúc đầu, nhưng nó trở nên khá dễ dàng để đối phó với họ cuối cùng, miễn là bạn phù hợp theo cách mà bạn đối phó với họ.

Các vấn đề liên quan