2010-02-12 41 views
7

Tôi có một lớp học với phương thức trả về băm. Thông thường, tôi sẽ nhận được kết quả như sau:Làm cách nào để quyết định một băm được trả về từ một phương thức của một lớp?

%resp = $myclass->sub($foo); 

Và sau đó các thành viên truy cập của băm trở lại như thế này:

$resp{key}{subkey}; 

trong trường hợp của một hash 2d.

Tôi hình dung thì phải có một cách để kết hợp này thành một dòng thanh lịch duy nhất, một cái gì đó như thế này:

$myclass->sub($foo)->{key}{subkey} 

Điều này rõ ràng là không dereferenced đúng như Perl trả về này khi cố gắng chạy mã:

Can't use string ("1/8") as a HASH ref

Trong cố gắng chuỗi dereferencing ngẫu nhiên, từ tìm "References quick reference" on Perlmonks, tôi đã đưa ra những điều sau đây, trong đó Perl không phàn nàn về, nhưng cũng không trả lại những gì tôi đang tìm kiếm:

$%{$myclass->sub($foo)}->{key}{subkey} 

Ai đó có thể cho tôi biết chuỗi thoát khỏi cuộc hội thảo dereferencing là gì?

+1

Mọi người dường như muốn làm cho cuộc sống ở đó trở nên khó khăn hơn bằng cách chuyển hai dòng hoàn toàn thành một dòng sai. Chắc chắn có những điều tốt hơn để suy nghĩ về. :) –

Trả lời

1

Chỉ cần trả về một hashref thay vì một băm:

$myclass->sub($foo)->{key}->{subkey}

+0

Kết quả tương tự như với -> trước {key}. Cảm ơn. – sgsax

+0

Cùng một kết quả nếu tôi rút ra -> hoàn toàn. – sgsax

+0

Whazzup với -1? Giải pháp thứ hai hoạt động. – DVK

2

tôi muốn trả về một tài liệu tham khảo HASH từ tiểu thay thế. Nếu không (có thể) giá trị băm của bạn được chuyển thành DANH SÁCH, sau đó lại vào HASH một lần nữa mà không có lý do:

sub mysub() { 
    ... 
    return \%myhash; 
} 

Có ít sự sao chép khi tham chiếu trở nên hiệu quả hơn.

+2

hàm băm được chuyển thành danh sách, không phải mảng. sự khác biệt là tinh tế nhưng quan trọng. –

+0

Tôi có thể thực hiện công việc đó. Bạn có thể giải thích lợi thế của việc trả về một hashref thay vì một băm? Tôi có thể làm lại các phương pháp khác trong lớp một cách dễ dàng. Cảm ơn! – sgsax

+0

Cảm ơn Eric. Tôi muốn viết DANH SÁCH nhưng đã lâu rồi. Perl của tôi bây giờ đã khá mạnh. – ziya

6

Thay đổi phụ để trả về một tài liệu tham khảo băm sẽ làm việc tốt nhất, nhưng để có được những chức năng mà bạn đang tìm kiếm:

{ $myclass->sub($foo) }->{key}{subkey} 

mà sẽ tạo ra một tài liệu tham khảo băm từ danh sách được trả về bởi sub, và sau đó ngay lập tức dereference it

Chỉnh sửa: Lợi thế để trả về hashref từ tiểu của bạn chứ không phải là băm (dưới dạng danh sách) phần lớn là một hiệu suất. Trong trường hợp hashref, băm được tạo một lần và sau đó được truy cập. Trong trường hợp danh sách, hàm băm được tạo, sau đó được chuyển đổi thành một danh sách, sau đó được tạo lại, và sau đó được bỏ qua. Đối với băm nhỏ này sẽ không mất quá nhiều thời gian, nhưng đối với những cái lớn hơn, nó chỉ là công việc không cần thiết cho thời gian chạy. Về cơ bản, nếu bạn dự định sử dụng dữ liệu dưới dạng danh sách ở một số địa điểm và dưới dạng băm ở những nơi khác, việc trả lại băm dưới dạng danh sách là ok. Nhưng nếu bạn luôn có kế hoạch sử dụng nó như một băm, trả về tham chiếu là rõ ràng hơn và nhanh hơn.

+0

Điều đó cho tôi biết chính xác những gì tôi đang tìm trong khi duy trì mã lớp hiện tại của mình. Cảm ơn! – sgsax

9

Những gì bạn đang cố gắng làm không thanh lịch cũng không được khuyến khích. Bạn đã quản lý bằng cách nào đó để gọi thường trình trong ngữ cảnh vô hướng (đó là những gì mà "1/8" tương ứng với).

Trả lại tham chiếu băm.

Bây giờ, hãy xem tại địa chỉ:

#!/usr/bin/perl 

package My::Mine; 

use strict; use warnings; 

sub test { 
    my %h = (
     a => { z => 1}, 
     b => { y => 2}, 
    ); 
    return %h; 
} 

package main; 

use strict; use warnings; 

my $class = 'My::Mine'; 

print { $class->test }->{a}{z}, "\n"; 

Điều đó sẽ không làm việc. Thay vào đó, bạn sẽ phải làm:

print +{ $class->test }->{a}{z}, "\n"; 

Bây giờ, đó là thanh lịch Xem perldoc -f print (Không!).

Ngắn câu chuyện, trả lại tham chiếu đến hàm băm.

Lưu ý rằng băm vô danh mới mà bạn đang xây dựng không phải là miễn phí. Cũng không phải là chi phí trả lại một băm dưới dạng danh sách phẳng từ một chương trình con.

+0

Tôi không nhận được nội dung + được sử dụng cho đây. Tôi đánh giá cao sự giáo dục. Cảm ơn. – sgsax

+3

+1 để giải thích 1/8 rõ ràng. Ngoài ra, một nhược điểm nữa là trả về băm - nó làm bạn mất ý thức về bảo mật nếu bạn nghĩ "đây là bản sao, vì vậy tôi có thể sửa đổi nó một cách an toàn" - chưa, phần bên trong của cấu trúc dữ liệu vẫn là refs không nhân bản sâu để bạn không thể sửa đổi chúng một cách an toàn. – DVK

+2

dấu + là một gợi ý cho trình phân tích cú pháp mà {...} xây dựng sau khi in không phải là một đối tượng gián tiếp cho phương thức in. điều này được sử dụng trong các tình huống như 'print {sub_returns_a_file_handle()}" nội dung cần in - lưu ý rằng không có dấu phẩy trước dấu ngoặc mở ";' –

0

Nếu bạn luôn muốn chỉ nhận một khóa con, hãy viết một chương trình con ngắn để thực hiện điều đó cho bạn và quên cách chơi gôn cho tuyến đường của bạn. Một lợi thế là bạn có thể dễ dàng thêm một số kiểm tra sanity:

sub get_subkey { 
     my($class, $arg, $key, $subkey) = @_; 

     my $hashref = $class->method($arg); 
     return unless ref $hashref; 

     return $hashref->{$key}{$subkey}; 
     } 
Các vấn đề liên quan