2009-07-20 11 views
5

Tôi gặp khó khăn với phương pháp BUILD trong MooseX::Declare. Nếu tôi nói:Cách thích hợp để tạo phương thức BUILD trong MooseX :: Khai báo là gì?

#!/usr/bin/perl 

use MooseX::Declare; 

class Foo { 
    has foo => (is => "rw", isa => "Str", default => "foo"); 

    method BUILD { 
     print "I was called\n"; 
    } 
} 

Foo->new; 

tôi nhận được sau ít hơn thông báo lỗi hữu ích:

Reference found where even-sized list expected at /Users/cowens/perl5/lib/perl5/MooseX/Method/Signatures/Meta/Method.pm line 335. 
Validation failed for 'MooseX::Types::Structured::Tuple[MooseX::Types::Structured::Tuple[Object],MooseX::Types::Structured::Dict[]]' failed with value [ [ Foo=HASH(0x804b20) ], { HASH(0x8049e0) => undef } ], Internal Validation Error is: Validation failed for 'MooseX::Types::Structured::Dict[]' failed with value { HASH(0x8049e0) => undef } at /Users/cowens/perl5/lib/perl5/MooseX/Method/Signatures/Meta/Method.pm line 365 
     MooseX::Method::Signatures::Meta::Method::validate('MooseX::Method::Signatures::Meta::Method=HASH(0xb8aab0)', 'ARRAY(0xb8ab30)') called at /Users/cowens/perl5/lib/perl5/MooseX/Method/Signatures/Meta/Method.pm line 139 
     Foo::BUILD('Foo=HASH(0x804b20)', 'HASH(0x8049e0)') called at generated method (unknown origin) line 25 
     Foo::new('Foo') called at test.pl line 13 

Nhưng nếu tôi nói:

#!/usr/bin/perl 

use MooseX::Declare; 

class Foo { 
    has foo => (is => "rw", isa => "Str", default => "foo"); 

    sub BUILD { 
     my $self = shift; 
     print "I was called\n"; 
    } 
} 

Foo->new; 

mọi thứ hoạt động tốt (nhưng là xấu xí và ngoài vị trí với phần còn lại của mã).

Trả lời

-2

Perl hiểu sub và do đó, một mục nhập vào bảng biểu tượng của gói hiện tại được thực hiện. & Foo :: BUILD, sau Devel::Declare và phép thuật khác đã tạo ra một phạm vi gói từ việc đóng lớp.

Moose dành riêng cho phụ BUILD để cho phép bạn thao tác với logic của hàm tạo. Đoán của tôi (mặc dù tôi đã không truy tìm nó tất cả các cách thông qua) là các mô-đun MooseX ở lại trên con đường của những gì Moose đang cố gắng để làm. Vì vậy, một bản địa BUILD là vĩnh viễn được truyền cho phép thuật Moose để xác định logic của hàm tạo.

Mặt khác, từ khóa method là nhiều hơn Devel::Declare phép thuật để tạo các phương thức trong cấu trúc lớp meta.

5

Không thành công vì BUILD yêu cầu chữ ký phương thức một arg. Theo mặc định, MooseX::Declare tạo chữ ký không tương thích với cách BUILD được gọi. (Các chi tiết thì thầm với tôi.) Tôi biết vì tôi đã gặp một lỗi tương tự một lần. Tôi chắc chắn đồng ý thông báo lỗi có thể khai sáng hơn; đó là sự thật với rất nhiều thứ Moose.

Dù sao, tôi đã nhận nó làm việc như thế này:

use MooseX::Declare; 

class Foo { 
    has foo => (is => "rw", isa => "Str", default => "foo"); 

    method BUILD(Item $href) { 
     print "I was called\n"; 
    } 
} 

Foo->new; 

Hy vọng rằng sẽ giúp.

Bạn có thể fiddle bằng chữ ký và thử các loại cụ thể hơn; Tôi nghĩ rằng Moose gửi một hashref của đối tượng như chưa được unblessed như tham số.

+0

Wow, đó là xấu xí, '$ self' tồn tại và giữ đối tượng may mắn, nhưng bạn cũng có hashref vô dụng này đầy đủ các đối số được chuyển thành 'mới'. Đây là một mụn cóc lớn trên những gì nếu không là một hệ thống đẹp. –

+0

"mụn cóc" này có thể là thứ gì đó sẽ bị xóa. Khi bạn xem các tài liệu cũ (http://search.cpan.org/~drolsky/Moose-0.65/lib/Moose/Cookbook/Basics/Recipe4.pod), bạn sẽ thấy rằng tham số thêm hashref arg là cần thiết. Tuy nhiên, trong tài liệu mới (http://search.cpan.org/dist/Moose/lib/Moose/Cookbook/Basics/Recipe4.pod), bạn có thể sử dụng $ self trực tiếp để truy cập vào "params". Vì vậy, có lẽ là một phần của quá trình tiến hóa, nơi thông số bổ sung này sẽ bị loại bỏ! Danh sách gửi thư Moose/IRC là nơi tốt nhất để tìm hiểu xem "params" arg vẫn còn cần thiết và kế hoạch Darwin là gì ;-) – draegtun

+0

Một đối số cho một phương pháp là một "mụn cóc lớn"? Tôi ghét phải nghe những gì bạn nghĩ về hệ thống đối tượng C++ hoặc Java ... – jrockway

6

BUILD mất một arg, nếu bạn không cần nó, chỉ cần nói:

method BUILD($) { ... }