2010-07-20 49 views
6

Tôi hiện đang ủy quyền phương thức trình xây dựng cho tất cả các đối tượng mở rộng một trong các lớp cơ sở của tôi. Vấn đề mà tôi đang phải đối mặt là tôi cần tất cả các đối tượng để đọc một thuộc tính của chính nó hoặc được chuyển vào một giá trị.Đối số cho trình xây dựng chương trình con trong đối tượng con nai

# In Role: 
has 'const_string' => (
    isa  => 'Str', 
    is  => 'ro', 
    default => 'test', 
); 

has 'attr' => (
    isa  => 'Str', 
    is  => 'ro', 
    builder => '_builder', 
); 

requires '_builder'; 


# In extending object - desired 1 
sub _builder { 
    my ($self) = shift; 
    # $self contains $self->const_string 
} 

# In extending object - desired 2 
sub _builder { 
    my ($arg1, $arg2) = @_; 
    # $args can be passed somehow? 
} 

Hiện tại điều này có khả thi hay tôi sẽ phải thực hiện theo cách khác?

+2

Tôi đang gặp rắc rối tìm hiểu chính xác những gì nó là bạn đang cố gắng để đạt được, có lẽ giải thích nó từ một góc độ người tiêu dùng? –

Trả lời

12

Bạn không thể chuyển đối số cho các phương thức tạo thuộc tính. Chúng được gọi tự động bởi Moose internals, và chỉ truyền một đối số - chính đối tượng tham chiếu. Người xây dựng phải có khả năng trả lại giá trị của nó dựa trên những gì nó thấy trong $self hoặc bất kỳ thứ gì khác trong môi trường mà nó có quyền truy cập.

Loại đối số nào bạn muốn chuyển cho người xây dựng? Thay vào đó, bạn có thể chuyển các giá trị này cho hàm tạo đối tượng và lưu trữ chúng trong các thuộc tính khác không?

# in object #2: 
has other_attr_a => (
    is => 'ro', isa => 'Str', 
); 
has other_attr_b => (
    is => 'ro', isa => 'Str', 
); 

sub _builder 
{ 
    my $self = shift; 
    # calculates something based on other_attr_a and other_attr_b 
} 

# object #2 is constructed as: 
my $obj = Class2->new(other_attr_a => 'value', other_attr_b => 'value'); 

Cũng lưu ý rằng nếu bạn có các thuộc tính được xây dựng dựa trên các giá trị thuộc tính khác, bạn nên xác định chúng như lazy, nếu không xây dựng/giá trị mặc định sẽ chạy ngay lập tức về xây dựng đối tượng, và trong một trật tự xác định. Đặt họ lười biếng sẽ trì hoãn định nghĩa của họ cho đến khi họ là cần thiết đầu tiên.

+1

Tôi chỉ cần thiết lập lười biếng và mọi thứ hoạt động hoàn hảo. Trong thử nghiệm ban đầu của tôi, tôi đã không có thiết lập để tôi không thể nhìn thấy các thuộc tính khác trong phương pháp xây dựng của tôi. Cảm ơn! – lespea

+0

@lespea: ngọt ngào! vui mừng khi nghe nó tất cả đã làm việc cho bạn! :) – Ether

0

Bạn có thể làm một cái gì đó như thế này:

has 'attr' => (
isa  => 'Str', 
is  => 'ro', 
builder => '_pre_builder', 
); 

sub pre_builder { 
    _builder(@_, 'your_arg'); 
} 
Các vấn đề liên quan