2009-07-21 26 views
22

Tôi đã được yêu cầu sửa đổi một số mã hiện có để thêm một số chức năng bổ sung. Tôi đã tìm kiếm trên Google và dường như không thể tìm thấy câu trả lời. Tôi có một cái gì đó để có hiệu lực này ...Làm thế nào tôi có thể sử dụng băm làm đối số cho các chương trình con trong Perl?

%first_hash = gen_first_hash(); 
%second_hash = gen_second_hash(); 
do_stuff_with_hashes(%first_hash, %second_hash); 

sub do_stuff_with_hashes 
{ 
    my %first_hash = shift; 
    my %second_hash = shift; 

    # do stuff with the hashes 
} 

Tôi nhận được các lỗi sau đây:

Odd number of elements in hash assignment at ./gen.pl line 85. 
Odd number of elements in hash assignment at ./gen.pl line 86. 
Use of uninitialized value in concatenation (.) or string at ./gen.pl line 124. 
Use of uninitialized value in concatenation (.) or string at ./gen.pl line 143. 

dòng 85 và 86 là hai dòng đầu tiên trong các thói quen tiểu và 124 và 143 là nơi tôi đang truy cập vào băm. Khi tôi tra cứu những lỗi này, có vẻ như gợi ý rằng băm của tôi chưa được khởi tạo. Tuy nhiên, tôi có thể xác minh rằng hashes có giá trị. Tại sao tôi nhận được các lỗi này?

+1

Đây là bản sao. Vui lòng xem http://stackoverflow.com/questions/944784/ – innaM

Trả lời

24

Các băm đang được thu gọn thành các danh sách phẳng khi bạn chuyển chúng vào hàm. Vì vậy, khi bạn thay đổi một giá trị từ các đối số của hàm, bạn chỉ nhận được một giá trị. Những gì bạn muốn làm là vượt qua băm bằng cách tham chiếu.

do_stuff_with_hashes(\%first_hash, \%second_hash); 

Nhưng sau đó bạn phải làm việc với băm dưới dạng tham chiếu.

my $first_hash = shift; 
my $second_hash = shift; 
+0

Tôi hiểu ... Điều đó đã làm được điều đó ... Cảm ơn rất nhiều! – predhme

5

Trước hết,

do_stuff_with_hashes(%first_hash, %second_hash); 

"suối" băm vào một danh sách, tương đương với:

('key1_1', 'value1', ... , 'key1_n', 'value1_n', 'key2_1', 'value2_1', ...) 

và sau đó bạn chọn một và chỉ một trong những mặt hàng này. Vì vậy,

my %first_hash = shift; 

cũng giống như nói:

my %first_hash = 'key1_1'; 
# leaving ('value1', ... , 'key1_n', 'value1_n', 'key2_1', 'value2_1', ...) 

Bạn không thể có một hash như { 'key1' }, vì 'key1' là lập bản đồ không có gì.

+1

Cảm ơn bạn đã giải thích những gì đang diễn ra đằng sau hậu trường. – predhme

9

Tham chiếu băm là cách để đi, như những người khác đã chỉ ra.

Cung cấp một cách khác để thực hiện điều này chỉ để đá ... vì ai cần biến tạm thời?

do_stuff_with_hashes({ gen_first_hash() }, { gen_second_hash() }); 

Tại đây bạn chỉ cần tạo tham chiếu băm khi đang di chuyển (qua dấu ngoặc nhọn xung quanh cuộc gọi hàm) để sử dụng trong hàm do_stuff_with_hashes của bạn. Điều này là không có gì đặc biệt, các phương pháp khác chỉ là hợp lệ và có thể rõ ràng hơn. Điều này có thể giúp giảm bớt con đường nếu bạn thấy hoạt động này trong chuyến du lịch của mình với tư cách là người mới tham gia Perl.

+0

Bí quyết tuyệt vời! Ill giữ nó xung quanh. – predhme

+0

Vui vẻ bắt buộc. Một điều cần lưu ý nếu bạn quan tâm đến Perl là mọi người sẽ chỉ ra cách "Có nhiều cách để làm điều đó". Đó là một loại phước lành và một lời nguyền) tùy thuộc vào ý kiến ​​của bạn về những điều như vậy) trong lập trình Perl. Chúc vui vẻ! –

14

Một chút trễ nhưng,

Như đã nêu, bạn phải chuyển tham chiếu chứ không phải băm.

do_stuff_with_hashes(\%first_hash, \%second_hash); 

Nhưng nếu bạn cần/muốn sử dụng băm của mình như vậy, bạn có thể không quan tâm đến chúng.

sub do_stuff_with_hashes { 
    my %first_hash = %{shift()}; 
    my %second_hash = %{shift()}; 
}; 
+0

để được rõ ràng, tôi không dereferencing các băm, tôi đang sao chép chúng. – larelogio

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