もちろん、設定によって属性の初期引数の名前を変更できることは知っていますinit_arg
(例)
package Test {
use Moose;
has attr => (
is => 'ro',
isa => 'Str',
init_arg => 'attribute'
);
}
それは私を可能にするでしょう
Test->new({ attribute => 'foo' });
だがしかし
Test->new({ attr => 'foo' });
同時に
MooseX::Aliasesは実際にはこの動作をしますが、エイリアスを作成するとアクセサーも作成されます。私は現在、そのモジュールのコードを理解しようとしており、それがどのように機能するかを判断できないかどうかを確認して、その機能を (私が理解している方法で) 複製できるようにしています。誰かがここでそれを行う方法を例で説明できれば、それは素晴らしいことです.
MX:: Aliasesは実際にコンストラクターに渡されたものを置き換えることによってこれを行っているようaround initialize_instance_slot
ですが、実際にどのように呼び出されるのかはまだわかりません。私のテスト コードでは、実際には実行されていないからです。
BUILDARGS
私がやろうとしていることは、Meta Recipe3を介して属性に追加しているラベルの名前を介してアクセサーの設定を許可するためです。あなたは私がやっていると言うかもしれません
has attr => (
is => 'ro',
isa => 'Str',
alt_init_arg => 'attribute'
);
アップデート
これが、私がこれまでにやろうとしていることでなんとかうまくいったことです。
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
問題は、around
ブロックが実行されないことです。理由がわかりません。間違った場所などにラップしている可能性があります。