Vấn đề là các nguyên mẫu hàm của Perl không làm những gì mọi người nghĩ rằng họ làm. Mục đích của chúng là cho phép bạn viết các hàm sẽ được phân tích cú pháp giống như các hàm tích hợp của Perl.
Trước hết, các cuộc gọi phương thức hoàn toàn bỏ qua các nguyên mẫu. Nếu bạn đang lập trình OO, không quan trọng phương pháp của bạn có nguyên mẫu nào. (Vì vậy, họ không nên có bất kỳ nguyên mẫu nào.)
Thứ hai, nguyên mẫu không được thực thi nghiêm ngặt. Nếu bạn gọi một chương trình con với &function(...)
, nguyên mẫu sẽ bị bỏ qua. Vì vậy, chúng không thực sự cung cấp bất kỳ loại an toàn nào.
Thứ ba, chúng là những pha hành động ma quái ở khoảng cách xa. (Đặc biệt là $
nguyên mẫu, khiến tham số tương ứng được đánh giá trong ngữ cảnh vô hướng, thay vì ngữ cảnh danh sách mặc định.)
Đặc biệt, chúng làm cho việc chuyển các tham số từ mảng trở nên khó khăn. Ví dụ:
my @array = qw(a b c);
foo(@array);
foo(@array[0..1]);
foo($array[0], $array[1], $array[2]);
sub foo ($;$$) { print "@_\n" }
foo(@array);
foo(@array[0..1]);
foo($array[0], $array[1], $array[2]);
bản in:
a b c
a b
a b c
3
b
a b c
cùng với 3 cảnh báo về main::foo() called too early to check prototype
(nếu cảnh báo được bật). Vấn đề là một mảng (hoặc lát mảng) được đánh giá trong ngữ cảnh vô hướng trả về độ dài của mảng.
Nếu bạn cần viết một hàm hoạt động giống như một hàm tích hợp, hãy sử dụng một nguyên mẫu. Nếu không, đừng sử dụng nguyên mẫu.
Lưu ý: Perl 6 sẽ có các nguyên mẫu được tân trang lại hoàn toàn và rất hữu ích. Câu trả lời này chỉ áp dụng cho Perl 5.