2010-03-20 41 views
5

tôi đã được sử dụng Perl một thời gian, nhưng hôm nay tôi tình cờ gặp mã này:

sub function1($$) 
{ 
    //snip 
} 

gì này có nghĩa là trong Perl?

Trả lời

15

Đây là hàm có số prototype có hai đối số vô hướng.


Có những lập luận mạnh mẽ về việc không thực sự sử dụng nguyên mẫu Perl nói chung - như được nêu trong các nhận xét bên dưới. Luận điểm mạnh nhất có lẽ là:

Có một cuộc thảo luận về StackOverflow từ năm 2008:

Có một sự thay thế tốt trong module MooseX::Method::Signatures.

+0

cảm ơn !! tôi gần như đã tìm ra điều đó. BTW tại sao nó là cần thiết, một số loại và kiểm tra số trên các thông số, phải không? – sud03r

+0

Perl không yêu cầu nguyên mẫu; chúng hoàn toàn không bắt buộc. Tuy nhiên, cũng giống như trong mã C, việc cung cấp các nguyên mẫu có thể gây ra một số lỗi mà nếu không sẽ không bị phát hiện. Nhìn chung, chúng không được sử dụng thường xuyên, theo kinh nghiệm của tôi - một phần vì chúng là một bổ sung muộn cho ngôn ngữ, và một phần vì các lập trình viên Perl khai thác (cho tốt, về tổng thể) sự linh hoạt của các subs Perl không có nguyên mẫu, và một phần bởi vì mọi người không muốn tránh các lỗi tự động (dường như họ thích tìm chúng theo cách cứng). –

+3

Nguyên mẫu không được sử dụng trong Perl hiện đại vì chúng bị hỏng. Làm thế nào bị hỏng? Đây là một câu hỏi gần đây chỉ minh họa một trong số rất nhiều vấn đề của họ: http://stackoverflow.com/questions/2485106/why-do-printf-and-sprintf-behave-differently Prototypes không được sử dụng để kiểm tra kiểu, chúng là gợi ý để trình biên dịch, và Perl sẽ * ép buộc các đối số của người gọi để phù hợp với nguyên mẫu * ngay cả khi chúng sai. – rjh

11

Khi câu trả lời khác đề cập đến, $$ tuyên bố mẫu thử nghiệm. Câu trả lời khác không nói là nguyên mẫu là gì. Chúng không phải để xác thực đầu vào, chúng là các gợi ý cho trình phân tích cú pháp.

Hãy tưởng tượng bạn đã hai chức năng tuyên bố như:

sub foo($) { ... } 
sub bar($$) { ... } 

Bây giờ khi bạn viết một cái gì đó mơ hồ, như:

foo bar 1, 2 

Perl biết nơi để đặt các dấu ngoặc; thanh mất hai args, do đó, nó tiêu thụ hai gần nhất với nó. foo mất một arg, vì vậy nó có kết quả của quầy bar và hai args:

foo(bar(1,2)) 

Một ví dụ khác:

bar foo 2, 3 

cũng áp dụng; foo mất một arg, vì vậy nó được 2. thanh mất hai args, vì vậy nó được foo(2) và 3:

bar(foo(2),3) 

Đây là một phần khá quan trọng của Perl, vì vậy gạt bỏ nó như là "không bao giờ sử dụng" đang làm bạn một sự bất hòa. Gần như mọi chức năng nội bộ đều sử dụng nguyên mẫu, do đó, bằng cách hiểu cách chúng hoạt động trong mã của riêng bạn, bạn có thể hiểu rõ hơn cách chúng được sử dụng bởi nội trang dựng sẵn. Sau đó, bạn có thể tránh các dấu ngoặc đơn không cần thiết, làm cho mã dễ nhìn hơn.

Cuối cùng, một anti-pattern tôi sẽ cảnh báo bạn chống lại:

package Class; 
sub new ($$) { bless $_[1] } 
sub method ($) { $_[0]->{whatever} } 

Khi bạn đang gọi mã như phương pháp (Class->method hoặc $instance->method), việc kiểm tra nguyên mẫu là hoàn toàn vô nghĩa. Nếu mã của bạn chỉ có thể được gọi là một phương pháp, thêm một mẫu thử nghiệm là sai. Tôi đã thấy một số mô-đun phổ biến làm điều này (hello, XML::Compile), nhưng nó sai, do đó, không làm điều đó.Nếu bạn muốn ghi lại bao nhiêu args để vượt qua, như thế nào về:

sub foo { 
    my ($self, $a, $b) = @_; # $a and $b are the bars to fooify 
    .... 

hoặc

use MooseX::Method::Signatures; 

method foo(Bar $a, Bar $b) { # fooify the bars 
    .... 

Không giống như foo($$), đây là những ý nghĩa và dễ đọc.

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