Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7763829
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 1, 20262026-06-01T14:45:27+00:00 2026-06-01T14:45:27+00:00

I of course know that I can rename the init arg for an attribute

  • 0

I of course know that I can rename the init arg for an attribute by setting init_arg (e.g)

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

which would allow me to

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

but not

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

at the same time

MooseX::Aliases actually has this behavior, but creating an alias also creates accessors. I’m currently trying to understand the code in that module to see if I can’t determine how it does it, so that I can replicate said functionality (in a way I understand). If someone could explain how to do it here with an example that’d be great.

update it appears that MX::Aliases is doing this by way of replacing what’s actually passed to the constructor in an around initialize_instance_slot but I’m still not sure how that’s actually getting called, because in my test code my around isn’t actually getting executed.

update munging in BUILDARGS isn’t really an option because what I’m trying to do allow setting of the accessor via the name of the label I’m adding to the attribute via Meta Recipe3. You might say I’m doing

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

update

here’s what I’ve managed to work out with what I’m trying to do so far.

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

problem is that my around block is never being run and I’m not sure why, maybe I’m wrapping it in the wrong place or something.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-01T14:45:29+00:00Added an answer on June 1, 2026 at 2:45 pm

    MooseX::Aliases 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 MooseX::Aliases‘s Trait attribute.

    I suspect the reason your code isn’t being called is due to something going wrong when you try to register your trait. MooseX::Aliases uses Moose::Util::meta_attribute_alias rather than the old fashioned way you’re using here. Try replacing your Moose::Meta::Attribute::Custom::Trait::OtherName section with a call to Moose::Util::meta_attribute_alias 'OtherName'; inside your Role.

    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.

    I’ve gotten a simple version of this working up through immutable. This code is also on github.

    First the Attribute trait:

    package MooseX::AltInitArg::Meta::Trait::Attribute;
    use Moose::Role;
    use namespace::autoclean;
    Moose::Util::meta_attribute_alias 'AltInitArg';
    
    
    has alt_init_arg => (
        is         => 'ro',
        isa        => 'Str',
        predicate  => 'has_alt_init_arg',
    );
    
    
    around initialize_instance_slot => sub {
        my $orig = shift;
        my $self = shift;
        my ($meta_instance, $instance, $params) = @_;
    
        return $self->$orig(@_)
            # don't run if we haven't set any alt_init_args
            # don't run if init_arg is explicitly undef
            unless $self->has_alt_init_arg && $self->has_init_arg;
    
        if (my @alternates = grep { exists $params->{$_} } ($self->alt_init_arg)) {
            if (exists $params->{ $self->init_arg }) {
                push @alternates, $self->init_arg;
            }
    
            $self->associated_class->throw_error(
                'Conflicting init_args: (' . join(', ', @alternates) . ')'
            ) if @alternates > 1;
    
            $params->{ $self->init_arg } = delete $params->{ $alternates[0] };
        }
        $self->$orig(@_);
    };
    
    1;
    __END__
    

    Next the Class trait.

    package MooseX::AltInitArg::Meta::Trait::Class;
    use Moose::Role;
    use namespace::autoclean;
    
    around _inline_slot_initializer => sub {
        my $orig = shift;
        my $self = shift;
        my ($attr, $index) = @_;
    
        my @orig_source = $self->$orig(@_);
        return @orig_source
            # only run on aliased attributes
            unless $attr->meta->can('does_role')
                && $attr->meta->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->has_alt_init_arg && $attr->has_init_arg;
    
        my $init_arg = $attr->init_arg;
    
        return (
            'if (my @aliases = grep { exists $params->{$_} } (qw('
              . $attr->alt_init_arg . '))) {',
                'if (exists $params->{' . $init_arg . '}) {',
                    'push @aliases, \'' . $init_arg . '\';',
                '}',
                'if (@aliases > 1) {',
                    $self->_inline_throw_error(
                        '"Conflicting init_args: (" . join(", ", @aliases) . ")"',
                    ) . ';',
                '}',
                '$params->{' . $init_arg . '} = delete $params->{$aliases[0]};',
            '}',
            @orig_source,
        );
    };
    1;
    __END__
    

    Finally the Moose::Exporter glue.

    package MooseX::AltInitArg;
    use Moose();
    
    use Moose::Exporter;
    use MooseX::AltInitArg::Meta::Trait::Attribute;
    
    Moose::Exporter->setup_import_methods(
        class_metaroles => { class => ['MooseX::AltInitArg::Meta::Trait::Class'] }
    );
    
    1;
    __END__
    

    An example of how this is used then:

    package MyApp;
    use 5.10.1;
    use Moose;
    use MooseX::AltInitArg;
    
    has foo => (
        is            => 'ro',
        traits        => ['AltInitArg'],
        alt_init_arg => 'bar',
    );
    
    
    my $obj = MyApp->new( bar => 'bar' );
    say $obj->foo; # prints bar
    

    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.

    Good luck.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I know that I can use git commit --amend --file=path-to-my-new-message but this will amend
I know that I can simply use bucket array for associative container if I
Do you know any university which has its C++ course available online? I'm looking
How can I unlock or delete a file that is in use, so that
I know that you can store a bunch of Parent* objects in a vector.
I know that it is impossible to set percentages and that you can set
I know that await can't be used in catch clause. However I haven't really
I have several li floating left, I know that I can identify the ID
I know that polymorphism can add a noticeable overhead. Calling a virtual function is
I know that the question about turning on/off GPS programatically on android has been

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.