2009-11-09 19 views
5

Moose kullanıyorum ve projemde yöntem çağrılarını kaydırmam gerekiyor. Sarma kodumun en dış değiştirici olması önemlidir.Perl Moose Metodu Değiştiriciler: 'Önce' ve 'sonra' önce 'etrafında' ara '

use Moose::Util; 
Moose::Util::apply_all_roles(__PACKAGE__->meta, ('App:Roles::CustomRole')); 
__PACKAGE__->meta->make_immutable; 

Bu benim benim Rolün değiştiricileri olduğunu makul emin olmasını sağlar: Ne sonra Moose Rolü benim yöntemi düzenleyicileri koymak ve şimdiye kadar yaptığım böyle benim sınıfın sonunda bu rolü uygulamalı Son olarak tanımlanmış, bu yüzden bana "önce" ve "sonra" için doğru davranışı veriyor. (Rolde "önce" ve "sonra", ilk ve sonuncu olarak adlandırılır.)

Aslında bunun yeterli olacağını düşündüm, ama şimdi "etrafındaki" yöntemlerle benzer yöntemlerle sarmak zorundayım. Moose'un üzerine kurulu olduğu Class :: MOP, öncelikle "etrafında" değiştiricileri uygular, bu nedenle "önce" ve "sonra" dan önce çağrılırlar. Benim "etrafında" değiştirici almak için nasıl

CUSTOM ROLE before 
    CUSTOM ROLE around 
     before 2 
      before 1 
       around 
        method 
       around 
      after 1 
     after 2 
    CUSTOM ROLE around 
CUSTOM ROLE AFTER 

Herhangi bir fikir:

CUSTOM ROLE before 
    before 2 
     before 1 
      CUSTOM ROLE around 
       around 
        method 
       around 
      CUSTOM ROLE around 
     after 1 
    after 2 
CUSTOM ROLE AFTER 

Gerçekten böyle bir şey gerekir: Daha fazla ayrıntı için

, işte değiştiricilerin Şu anki arama sırasıdır İstediğim yerde/uygulanacak mı? Bazı sembollerin hacklemesini yapabildiğimi biliyorum (Class :: MOP zaten yapıyor) ama ben gerçekten değil.

+1

, :: yerine' with' daha apply_all_roles'? – perigrin

+0

Rolümdeki 'önce' ve 'sonra' değiştiricilerin, sınıfta zaten mevcut olabilecek diğer modifiye edicilerle karşılaştırıldığında ilk veya sonuncu olarak çalıştırılmasını istedim. Rolün manuel olarak uygulanması değiştiricileri daha sonra tanımlar ve sonra değiştiriciler ilk önce (önceki için) ve son (sonraki için) çalışır. –

+0

@perigrin Sonunda senin ve Ether'in sorusunu anladım. Rolü, düşündüğüm gibi apply_all_roles ile uygulamanıza gerek yok.Ben Moose için hala yeni ve rolünü manuel olarak uygulama ihtiyacı duyma fikrine asıldım. Yapmam gereken tek şey, dosyanın sonunda (diğer modifiye edicilerden sonra) baştan çok "ile" ile uygulamaktı. –

cevap

4

En basit çözüm, CUSTOM ROLE ana yöntemi çağıran ve sonra da onu sarmalayan bir yöntem tanımlamaktır.

role MyRole { 
    required 'wrapped_method'; 
    method custom_role_base_wrapper { $self->wrapped_method(@_) } 

    around custom_role_base_wrapper { ... } 
    before custom_role_base_wrapper { ... } 
} 

yaşadığınız sorun bir yöntem daha sarma şey diğer etrafında ÖZEL ROLÜ sahip çalışıyoruz olmasıdır. Hangi yapacağı tasarlanmamış. Benzer sembol tablosu korsanlığını yazmanız dışında (muhtemelen Moose insanlarından bir tanesinin Class: MOP'a ulaşmak için bir API'ye maruz kalmasına neden olabilirsiniz), düşünebildiğim tek diğer çözüm yukarıdakidir.

Eğer custom_role_base_wrapper katacak ekstra çağrı yığını çerçeve istemiyorsanız, sen Yuval adlı Sub::Call::Tail bakmak veya çağrı yığını işlemek için goto kullanarak olmalıdır.

neden `Moose :: Util kullanırken aşağıda eter sorusuna katılıyorum
+0

Özel sarmalayıcı fikriyle gittim. Bana ihtiyacım olan esnekliği sağladı, teşekkürler. –

3

Moose oldukça yeniyim ama bunu neden:

use Moose::Util; 
Moose::Util::apply_all_roles(__PACKAGE__->meta, ('App:Roles::CustomRole')); 

ziyade sadece bu? Sorunuza gelince

with 'App:Roles::CustomRole'; 

, bir hack biraz, ama before ve after yöntemlerle içine around yöntemi bölmek ve sınıf tanımının sonunda rolünü uygulamak (bu yüzden istediğiniz sırayla uygulanır olabilir)? Kesinlikle gerekliyse, iki yöntem arasında durum kaydetmek için özel öznitelikleri kullanabilirsiniz.

+1

Sorun şu ki, ne 'ne' ne ne de sonra 'geri' geri dönüş anlambilimini 'etrafındaki' olacak şekilde değiştirmenize izin vermez. Bu semantikler önemliyse, sen batırdın. Eğer değilse, neden başlamak için 'around' kullanıyorsunuz? – perigrin

+0

El ile uygulamamın nedeni, değiştiricilerin tanımlandıkları sıraya göre eklendikleri (ve sonra çalıştırdıkları) olmasıdır. Genellikle sipariş değiştiricilerin çalıştığı hakkında umursamıyorsunuz. Ama benim durumum, rolümün değiştiricilerini ilk önce ve sonuncu sırada olmak istedim. Rolleri uygulamak için "ile" sözdizimini kullanırsanız, değiştiricileri önce tanımlanır ve böylece en çok "önce" ve "sonra" olarak çalıştırılırlar. Rolü elle manuel olarak uygulayarak son olarak tanımlanırlar ve böylece olmasını istediğim zaman çalışırlar. –

+0

@Matt: Bu aslında Moose'un bir kusuru gibi görünüyor. Belki de “sonra” semantikleri, dönüş değeri “around” gibi değişmeye izin vermeli veya “before”, “around” ve “after” yöntemlerinin sırası değiştirilmelidir, böylece hepsi birbirlerine göre LIFO'dur. sadece kendilerine göre (eğer bu mantıklıysa). – Ether

İlgili konular