Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

MooseX::GetOpt disable in role

by Boldra (Deacon)
on Jun 21, 2013 at 10:11 UTC ( #1040122=perlquestion: print w/ replies, xml ) Need Help??
Boldra has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,

I have a lot (30 94 and growing) of MooseX::Getopt based scripts inheriting from a single role (My::App). My::App includes quite a few getopt-enabled switches which don't make sense in some of the scripts which inherit from it. The result is that when the user runs script --help, they get a page and a half of options which are irrelevant.

I can suppress some options from a script by adding following to the attribute declarations in the inheriting script:

has( "+$_", traits => ['NoGetopt'] ) for qw<fast_db html_output japane +se_wts debug_soap lease_tolerance>;

This is effective, but not pretty, and since I have so many classes which use it, it would be nice to put it into a sub in a shared package. My::App seems like the logical choice, but:

has '+attr' is not supported in roles ...

Which is fine with me, but I'm calling this in a class, it's just that Moose thinks I'm calling it in a role. has isn't a method, so I can't use my package to tell Moose that it's being called from a role. It looks like has is using caller to see where it's being called from.

So what do people suggest? Should I:

  1. Put the 'disable_getopt_attribute' code in a different (new) package (which will probably never contain anything else)
  2. Try to work out how to trick has into running in a role
  3. Cut and paste the ugly code in all my classes

What do you think?

Update Much more than 30


- Boldra

Comment on MooseX::GetOpt disable in role
Select or Download Code
Re: MooseX::GetOpt disable in role
by tobyink (Abbot) on Jun 21, 2013 at 10:58 UTC

    You haven't posted the code for your disable_getopt_attribute function, but I guess it looks a little like this:

    package My::App; use Moose::Role; # ... etc sub disable_getopt_attribute { has("+$_", traits => ['NoGetopt']) for @_; }

    And you're calling it like this from classes:

    package My::Script; use Moose; with "My::App"; My::App::disable_getopt_attribute(qw/ foo bar /);

    Try changing the definition to this:

    package My::App; use Moose::Role; # ... etc sub disable_getopt_attribute { my $class = shift; my $has = $class->can("has"); $has->("+$_", traits => ['NoGetopt']) for @_; }

    And calling it like this:

    package My::Script; use Moose; with "My::App"; __PACKAGE__->disable_getopt_attribute(qw/ foo bar /);

    This way, the has function that gets called, is My::Script's copy of has; not My::App's copy of it.

    package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name

      Thanks Tobyink!

      Your guess about how I was calling it was spot-on, and your solution works beautifully. I'm very grateful!



      - Boldra
      If you always want to disable the same attributes for MooseX::Getopt from your role, then this worked for me:
      package My::Role::Getopt { use Moose::Role; with 'My::Role::DB'; with 'My::Role::Log'; with 'MooseX::Getopt::Dashes'; before 'process_argv' => sub { my $self = shift; my @attrs_to_exclude_from_getopt = ( '+db', ... ); for my $attr (@attrs_to_exclude_from_getopt) { $self->meta->add_attribute($attr => (traits => ['NoGetopt' +])); } }; no Moose::Role; }

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1040122]
Approved by hdb
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (8)
As of 2015-07-07 03:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (86 votes), past polls