Tôi đã có yêu cầu chính xác này nhiều lần trong quá khứ và hôm nay tôi thực sự phải làm điều đó từ metaclass, điều này có nghĩa là không cho phép chỉnh sửa BUILD. Dù sao tôi cảm thấy nó sẽ là tốt để chia sẻ vì nó về cơ bản thực hiện chính xác những gì ether đề cập:
'Nó sẽ cho phép đánh dấu các thuộc tính "này là lười biếng, vì nó phụ thuộc trên các giá trị thuộc tính khác được xây dựng, nhưng tôi muốn . nó được chọc trước khi kết thúc xây dựng "'
Tuy nhiên, derp derp tôi không có ý tưởng làm thế nào để tạo ra một mô-đun CPAN vì vậy đây là một số mã: https://gist.github.com/TiMBuS/5787018
Đặt trên vào Late.pm và sau đó bạn có thể sử dụng i t như vậy:
package Thing;
use Moose;
use Late;
has 'foo' => (
is => 'ro',
default => sub {print "setting foo to 10\n"; 10},
);
has 'bar' => (
is => 'ro',
default => sub {print 'late bar being set to ', $_[0]->foo*2, "\n"; $_[0]->foo*2},
late => 1,
);
#If you want..
__PACKAGE__->meta->make_immutable;
1;
package main;
Thing->new();
#`bar` will be initialized to 20 right now, and always after `foo`.
#You can even set `foo` to 'lazy' or 'late' and it will still work.
Nguồn
2013-06-12 10:36:16
Bạn không nên sử dụng 'mặc định' cho điều đó? Tôi nghĩ rằng điểm 'lười biếng' là trì hoãn việc tạo giá trị thuộc tính cho đến lần sử dụng đầu tiên. Nếu bạn cần tất cả các thuộc tính được đặt ở cấu trúc đối tượng, 'mặc định' có vẻ hữu ích hơn. Hoặc, bạn có thể cung cấp phương thức 'BUILD' của riêng bạn. –
Đây là một thành ngữ khá phổ biến và có một số lý do hợp lý cho nó. – hobbs
Về cơ bản, bạn có thể làm tất cả công việc trong 'BUILD' thay vào đó, nhưng tốt hơn là nên có một phương thức cho mỗi thuộc tính. Và nếu bạn sẽ có một phương thức cho mỗi thuộc tính để tính giá trị thì nó cũng có thể là một người xây dựng. Nhưng nếu một người xây dựng sẽ truy cập các thuộc tính khác thì thuộc tính được xây dựng cần phải được lười biếng để chắc chắn rằng chúng đã được khởi tạo. Và không có tùy chọn thuộc tính "lười biếng, nhưng chỉ một chút * lười biếng" * – hobbs