Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

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

Replies are listed 'Best First'.
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?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1040122]
Approved by hdb
Front-paged by Corion
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (4)
As of 2018-06-18 10:37 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (109 votes). Check out past polls.