2013-09-23 42 views
6

Java'da soyut bir sınıf gibi davranan Moose :: Role sınıfını uygulamaya çalışıyorum. Rolde bazı yöntemleri uygulamak istiyorum, ama sonra bu yöntemleri somut sınıflarda geçersiz kılma yeteneğine sahip olmak istiyorum. Bunu, sınıfları genişletirken işe yarayan aynı stili kullanarak denerseniz, Cannot add an override method if a local method is already present hatasını aldım.Moose :: Rolünde bir alt nasıl geçersiz kılınır?

Benim soyut sınıf:

package AbstractClass; 

use Moose::Role; 

sub my_ac_sub { 

    my $self = shift; 

    print "In AbstractClass!\n"; 
    return; 
} 

1; 

Benim beton sınıfı: o zaman

package Class; 

use Moose; 

with 'AbstractClass'; 

override 'my_ac_sub' => sub { 

    my $self = shift; 

    super; 
    print "In Class!\n"; 
    return; 
}; 

__PACKAGE__->meta->make_immutable; 
1; 

Ve:

use Class; 

my $class = Class->new; 
$class->my_ac_sub; 

ben yanlış mı yapıyorum İşte bir örnek? Yapmaya çalıştığım şey farklı bir şekilde yapılması gerekiyor mu? Yapmamam gereken şey ne yapmaya çalışıyor?

+0

Soyut bir sınıfı modellemek için soyut bir sınıf kullanın! Bu basit bir şekilde yapıyı imkansızlaştırmanızı gerektirir (yani bir hata veren bir BUILDALL verin). – amon

+1

Muhtemelen bunu yapmanın Moose yolu, "my_ac_sub" gerektirir, "Rol", "değil", "sanal" yöntemidir. Moose :: Role daha sonra mevcut bir yöntemle oluşturulduğunu kontrol edecek, –

+1

Kodu çalıştırmayı denedim ve sonra 'sub my_ac_sub' ile geçersiz kılmayı değiştirdim ve aniden beklendiği gibi çalıştı. "Düzelt" ile ilgili bir sorun var mı? (Feragatname: Moose'a yeniyim). – Dallaylaen

cevap

4

o yanlış kullanıyordu ortaya çıktı. Ben a ticket açtı ve bunu yapmanın doğru yolu gösterildi:

package Class; 

use Moose; 

with 'AbstractClass'; 

around 'my_ac_sub' => sub { 

    my $next = shift; 
    my $self = shift; 

    $self->$next(); 
    print "In Class!\n"; 
    return; 
}; 

__PACKAGE__->meta->make_immutable; 
1; 

Bu değişikliği yapmak, istenen etkiye sahiptir.

2

Some time ago, Bunu yalnızca requires ifadelerinden oluşan bir rol oynayarak yaptım. Bu soyut temel sınıfı oluşturur. Ardından, başka bir sınıfta varsayılan uygulamaları koymak ve bundan devralabilir:

#!/usr/bin/env perl 

use 5.014; 

package AbstractClass; 

use Moose::Role; 

requires 'my_virtual_method_this'; 
requires 'my_virtual_method_that'; 

package DefaultImpl; 

use Moose; 
with 'AbstractClass'; 

sub my_virtual_method_this { 
    say 'this'; 
} 

sub my_virtual_method_that { 
    say 'that' 
} 

package MyImpl; 

use Moose; 
extends 'DefaultImpl'; 
with 'AbstractClass'; 

override my_virtual_method_that => sub { 
    super; 
    say '... and the other'; 
}; 

package main; 

my $x = MyImpl->new; 

$x->my_virtual_method_this; 
$x->my_virtual_method_that; 

birkaç yöntemler rolü tanımlamak sadece varsayılan uygulamaları sağlamak istiyorsanız, DefaultImpl den requires çıkarın.

Çıkış:

$ ./zpx.pl 
this 
that 
... and the other
+1

Bence bu iyi bir çalışma. "Temiz hissetmez", ancak bunun için bir istek listesi geliştirmesi göndereceğim. Bu cevap için teşekkür ederim. – Joel

İlgili konular