Puns sang một bên, tôi đang cố gắng thực hiện một phương thức import
trong lớp Perl của tôi để khởi tạo đối tượng Data
, về cơ bản là một mảng được tôn vinh của hashrefs. .Chết tiệt, Perl không thể ban phước cho đối tượng của tôi
Dưới đây là một ví dụ về làm thế nào tôi có kế hoạch để sử dụng nó:
# Pull in the data
my $data = Data->import(
[
{ a => 1, b => 7, c => 3},
{ a => 7, b => 9, c => 2},
]
);
$data->manipulate; # Use package methods
thực hiện import
của tôi là như sau:
package Data;
sub initialize {
my $class = shift;
my $data = [];
bless $data, $class;
return $data;
}
sub import {
my ($class, $data) = @_;
bless $data, $class;
return $data;
}
1;
Điều đáng ngạc nhiên là Perl báo cáo lỗi tại biên dịch -time (lưu ý khối BEGIN
):
Can't bless non-reference value at Data.pm line 51.
BEGIN failed--compilation aborted at myScript.pl line 8.
perldiag
không thêm nhiều rõ ràng với những gì đang xảy ra:
Can't bless non-reference value
(F)
Only hard references may be blessed. This is how Perl "enforces" encapsulation of objects. Seeperlobj
.
Tôi thậm chí đã cố gắng khởi tạo các đối tượng và bổ sung các dữ liệu theo hai bước riêng biệt:
sub import { #< Another constructor >
my ($class, $data) = @_;
my $obj = $class->initialize;
push @$obj, @$data;
return $obj;
}
Điều này dẫn đến lỗi biên dịch sau:
Can't use an undefined value as an ARRAY reference...
BEGIN failed--compilation aborted at...
Hai câu hỏi:
- Có gì sai với những gì tôi đã làm gì?
- Có thể ai đó vui lòng làm rõ giải thích
perldiag
về lỗi biên dịch này không?
Cảnh báo: Có tham chiếu nào tốt hơn 'perldiag' để hiểu thông báo cảnh báo/lỗi không? – Zaid
Nói chung, bạn có thể tấn công các lỗi như thế này bằng cách chèn một bản in các điều kiện tiên quyết của bạn. Trong trường hợp này, các đối số cho chương trình con của bạn. ('in 'nhập khẩu đã nhận: @_ \ n"; ') Điều đó sẽ cho bạn biết rằng những gì bạn nghĩ là một mảng thực sự là không. Tiếp theo, thêm một bảo vệ, một cái gì đó như 'ref $ data eq 'ARRAY' hoặc thú nhận" không phải là mảng: '$ data' ";' và bạn sẽ tìm ra nơi mà cuộc gọi vi phạm đến từ đó. ('confess' là từ' sử dụng Carp 'thú nhận'; 'và cung cấp một backtrace đầy đủ) Giữ dòng đó, vì nó có thể giúp bạn ngay lập tức bắt các lỗi khác trong tương lai, có lẽ thay đổi' confess' thành 'croak'. –
@Lance Roberts: Tiêu đề ban đầu là cách chơi trên các từ trong tham chiếu đến mô-đun ['Acme :: Damn'] (http://search.cpan.org/perldoc?Acme::Damn) (ngược lại với 'bless') – Zaid