2010-11-16 44 views
1

我有一個屬性特徵,我想在其他類屬性的基礎上設置。我真的希望獲得類$self的副本的屬性特徵的默認值,而不是屬性的元。我想在我的班級做這樣的事情:使用駝鹿,如何在運行時設置'ro'屬性特徵的值?

after 'BUILD' => sub {              
    my $self = shift;               
    $self->meta->get_attribute('id')->column_name($self->_unique_key_name); 
}; 

但是,我想保留我的屬性特徵RO?這可能嗎。我知道MOP允許設置類屬性的值,但我無法弄清楚如何在元屬性上設置屬性。

回答

1

這聽起來像一個非常奇怪的設計(爲什麼元類需要一個它正在描述的類的實例?) - 但是你可以通過使用元類的元類很容易地做到這一點(記住,Moose元類是

$self->meta->meta->get_attribute("foo")->default($some_value); 

還記得,默認需要被包裹在一個CODEREF如果他們引用自己: - 「默認」 $some_value = sub { $instance };


其實,這是不行的使用MOP本身)自舉是隻讀的。我不希望在如此低的水平上擺弄MOP,而是敦促你重新考慮你的設計 - 例如將你的'默認'存儲在另一個屬性中,然後寫入一個委託給它的默認子文件:

package MyApp::Meta::Attribute::Trait::Foo; 

# set at runtime, when we have an instance to store here 
has _default_of_foo => (
    is => 'rw', isa => 'Object', 
); 
has foo => (
    is => 'ro', isa => 'Object', 
    lazy => 1, 
    default => sub { shift->_default_of_foo }, 
); 
+0

我對這種實現沒有任何運氣。是否可能[' - > default'是隻讀的](http://search.cpan.org/~drolsky/Class-MOP-1.11/lib/Class/MOP/Attribute.pm#Informational) – 2010-11-16 18:02:43

+0

@Evan:correct ,啊!編輯答案。 – Ether 2010-11-16 18:41:53

+0

沒錯,但這並不能解釋潛在的問題。如果'default'需要訪問'$ self'(class)'shift',那麼沒有從使用該屬性的類實例化的對象。這是屬性的一些模糊元素。 – 2010-11-16 19:14:58