Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p><code>MooseX::Aliases</code> has several moving parts to make this functionality happen, that's because the behavior needs to be applied to several different places in the MOP. Your code here looks very close to the code in <code>MooseX::Aliases</code>'s Trait attribute.</p> <p>I suspect the reason your code isn't being called is due to something going wrong when you try to register your trait. <code>MooseX::Aliases</code> uses <code>Moose::Util::meta_attribute_alias</code> rather than the old fashioned way you're using here. Try replacing your <code>Moose::Meta::Attribute::Custom::Trait::OtherName</code> section with a call to <code>Moose::Util::meta_attribute_alias 'OtherName';</code> inside your Role.</p> <p>Second the code you have here won't work for immutable classes. You'll need to add a second trait to handle those because the immutability code is handled by the class's metaclass and not the attribute's metaclass. You'll need to add some more traits to handle attributes in Roles as well I think. Then you'll need to wire up an Moose::Exporter to make sure that all the traits are applied properly when everything is compiled.</p> <p>I've gotten a simple version of this working up through immutable. This code is also on <a href="https://github.com/perigrin/MooseX-AltInitArg" rel="nofollow">github</a>.</p> <p>First the Attribute trait:</p> <pre><code>package MooseX::AltInitArg::Meta::Trait::Attribute; use Moose::Role; use namespace::autoclean; Moose::Util::meta_attribute_alias 'AltInitArg'; has alt_init_arg =&gt; ( is =&gt; 'ro', isa =&gt; 'Str', predicate =&gt; 'has_alt_init_arg', ); around initialize_instance_slot =&gt; sub { my $orig = shift; my $self = shift; my ($meta_instance, $instance, $params) = @_; return $self-&gt;$orig(@_) # don't run if we haven't set any alt_init_args # don't run if init_arg is explicitly undef unless $self-&gt;has_alt_init_arg &amp;&amp; $self-&gt;has_init_arg; if (my @alternates = grep { exists $params-&gt;{$_} } ($self-&gt;alt_init_arg)) { if (exists $params-&gt;{ $self-&gt;init_arg }) { push @alternates, $self-&gt;init_arg; } $self-&gt;associated_class-&gt;throw_error( 'Conflicting init_args: (' . join(', ', @alternates) . ')' ) if @alternates &gt; 1; $params-&gt;{ $self-&gt;init_arg } = delete $params-&gt;{ $alternates[0] }; } $self-&gt;$orig(@_); }; 1; __END__ </code></pre> <p>Next the Class trait. </p> <pre><code>package MooseX::AltInitArg::Meta::Trait::Class; use Moose::Role; use namespace::autoclean; around _inline_slot_initializer =&gt; sub { my $orig = shift; my $self = shift; my ($attr, $index) = @_; my @orig_source = $self-&gt;$orig(@_); return @orig_source # only run on aliased attributes unless $attr-&gt;meta-&gt;can('does_role') &amp;&amp; $attr-&gt;meta-&gt;does_role('MooseX::AltInitArg::Meta::Trait::Attribute'); return @orig_source # don't run if we haven't set any aliases # don't run if init_arg is explicitly undef unless $attr-&gt;has_alt_init_arg &amp;&amp; $attr-&gt;has_init_arg; my $init_arg = $attr-&gt;init_arg; return ( 'if (my @aliases = grep { exists $params-&gt;{$_} } (qw(' . $attr-&gt;alt_init_arg . '))) {', 'if (exists $params-&gt;{' . $init_arg . '}) {', 'push @aliases, \'' . $init_arg . '\';', '}', 'if (@aliases &gt; 1) {', $self-&gt;_inline_throw_error( '"Conflicting init_args: (" . join(", ", @aliases) . ")"', ) . ';', '}', '$params-&gt;{' . $init_arg . '} = delete $params-&gt;{$aliases[0]};', '}', @orig_source, ); }; 1; __END__ </code></pre> <p>Finally the <code>Moose::Exporter</code> glue.</p> <pre><code>package MooseX::AltInitArg; use Moose(); use Moose::Exporter; use MooseX::AltInitArg::Meta::Trait::Attribute; Moose::Exporter-&gt;setup_import_methods( class_metaroles =&gt; { class =&gt; ['MooseX::AltInitArg::Meta::Trait::Class'] } ); 1; __END__ </code></pre> <p>An example of how this is used then:</p> <pre><code>package MyApp; use 5.10.1; use Moose; use MooseX::AltInitArg; has foo =&gt; ( is =&gt; 'ro', traits =&gt; ['AltInitArg'], alt_init_arg =&gt; 'bar', ); my $obj = MyApp-&gt;new( bar =&gt; 'bar' ); say $obj-&gt;foo; # prints bar </code></pre> <p>Meta-Programming in Moose is incredibly powerful, but because there are a lot of moving parts (many of which have solely to do with maximizing performance) you bite off a lot of work when you dive in. </p> <p>Good luck.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload