Jak mogę podać alternatywny argument inicjujący dla atrybutu w Moose?

Oczywiście wiem, że mogę zmienić nazwę argumentu inicjującego dla atrybutu, ustawiającinit_arg (na przykład)

<code>package Test {
    use Moose;
    has attr => (
       is => 'ro',
       isa => 'Str',
       init_arg => 'attribute'
    );
}
</code>

co mi pozwoli

<code>Test->new({ attribute => 'foo' });
</code>

ale nie

<code>Test->new({ attr => 'foo' });
</code>

w tym samym czasie

MooseX :: Aliasy faktycznie ma to zachowanie, ale tworzenie aliasu tworzy także akcesoria. Obecnie próbuję zrozumieć kod w tym module, aby sprawdzić, czy nie mogę określić, jak to robi, aby móc replikować wspomnianą funkcjonalność (w pewien sposób, który rozumiem). Jeśli ktoś mógłby wyjaśnić, jak to zrobić tutaj, z przykładem, który byłby świetny.

aktualizacja wygląda na to, że MX :: Aliases robi to poprzez zastąpienie tego, co faktycznie przekazano konstruktorowi waround initialize_instance_slot ale wciąż nie jestem pewien, jak to się właściwie nazywa, ponieważ w moim kodzie testowym moje okolice nie są w rzeczywistości wykonywane.

aktualizacja wmieszanie sięBUILDARGS tak naprawdę nie jest opcją, ponieważ to, co próbuję zrobić, zezwala na ustawienie akcesorium za pomocą nazwyetykieta Dodaję do atrybutu przezMeta Recipe3. Możesz powiedzieć, że robię

<code>has attr => (
   is => 'ro',
   isa => 'Str',
   alt_init_arg => 'attribute'
);
</code>

aktualizacja

oto, co udało mi się wypracować z tym, co staram się robić do tej pory.

<code>use 5.014;
use warnings;

package MooseX::Meta::Attribute::Trait::OtherName {
    use Moose::Role;
    use Carp;

    has other_name => (
        isa       => 'Str',
        predicate => 'has_other_name',
        required  => 1,
        is        => 'ro',
    );

    around initialize_instance_slot => sub {
        my $orig = shift;
        my $self = shift;

        my ( $meta_instance, $instance, $params ) = @_;

        confess 'actually calling this code';

        return $self->$orig(@_)
            unless $self->has_other_name && $self->has_init_arg;

        if ( $self->has_other_name ) {
            $params->{ $self->init_arg }
                = delete $params->{ $self->other_name };
        }
    };
}

package Moose::Meta::Attribute::Custom::Trait::OtherName {
    sub register_implementation { 'MooseX::Meta::Attribute::Trait::OtherName' }
}

package Message {
    use Moose;
#   use MooseX::StrictConstructor;

    has attr => (
        traits    => [ 'OtherName' ],
        is        => 'ro',
        isa       => 'Str',
        other_name => 'Attr',
    );

    __PACKAGE__->meta->make_immutable;
}

package Client {
    use Moose;

    sub serialize {
        my ( $self, $message ) = @_;

        confess 'no message' unless defined $message;

        my %h;
        foreach my $attr ( $message->meta->get_all_attributes ) {
            if (
                    $attr->does('MooseX::Meta::Attribute::Trait::OtherName')
                    && $attr->has_other_name
                ) {
                $h{$attr->other_name} = $attr->get_value( $message );
            }
        }
        return \%h;
    }
    __PACKAGE__->meta->make_immutable;
}

my $message = Message->new( Attr => 'foo' );

my $ua = Client->new;

my %h = %{ $ua->serialize( $message )};

use Data::Dumper::Concise;

say Dumper \%h
</code>

problem polega na tym, że mójaround blok nigdy nie jest uruchamiany i nie jestem pewien dlaczego, może zawijam go w niewłaściwe miejsce lub coś takiego.

questionAnswers(3)

yourAnswerToTheQuestion