2010-10-23 3 views
1

Après phaylon's answer to "How can I flexibly add data to Moose objects?", supposons que je l'attribut Moose suivante:Comment puis-je modifier un descripteur d'attribut Moose?

has custom_fields => (
    traits  => [qw(Hash)], 
    isa  => 'HashRef', 
    builder => '_build_custom_fields', 
    handles => { 
     custom_field   => 'accessor', 
     has_custom_field  => 'exists', 
     custom_fields  => 'keys', 
     has_custom_fields => 'count', 
     delete_custom_field => 'delete', 
    }, 
); 

sub _build_custom_fields { {} } 

Maintenant, supposons que je voudrais croasser si vous essayez de lire (mais pas écrire) à un champ personnalisé non existant. J'ai été suggéré par phaylon pour envelopper custom_field avec un modificateur autour. J'ai expérimenté avec les modificateurs around en suivant les divers exemples dans les docs de Moose, mais je n'ai pas pu comprendre comment modifier un handle (plutôt qu'une simple méthode d'objet).

D'autre part, existe-t-il une autre façon d'implémenter cette clé croak-if-try-to-read-nonexisting-key?

Répondre

6

Ce ne sont encore que des méthodes générées par Moose. Vous pouvez juste faire:

around 'custom_field' => sub { 
    my $orig = shift; 
    my $self = shift; 
    my $field = shift; 

    confess "No $field" unless @_ or $self->has_custom_field($field); 

    $self->$orig($field, @_); 
}; 

(.. croak est pas très utile dans les modificateurs de méthode au moment où il va simplement vous indiquer au code de Moose interne)

En fait, vous n'avez pas besoin d'utiliser around pour cela. L'utilisation de before est plus simple:

before 'custom_field' => sub { 
    my $self = shift; 
    my $field = shift; 

    confess "No $field" unless @_ or $self->has_custom_field($field); 
}; 
+0

@David B, 'handles' crée des méthodes d'objet standard. Un objet ne peut pas avoir deux méthodes avec le même nom. Comment pourrait-il savoir lequel vous appeliez? (Perl 5 n'a pas de multiméthodes.) – cjm

+0

+1 Merci cjm. J'essayais d'éditer mon commentaire auquel vous avez répondu, mais je l'ai effacé accidentellement. Juste pour le compte rendu, je demandais quelque chose comme "que se passe-t-il si deux attributs ont un pseudo avec le même nom". Apparemment, c'est impossible. Merci encore! –

+2

@David juste pour clarifier, l'option 'handles' est destinée à être lue comme le verbe 'gère', pas le nom 'handles'. Comme dans "cet attribut * gère * ces méthodes", pas "cet attribut a ces handles". C'est un outil de délégation. – hobbs

Questions connexes