Cagao has asked for the wisdom of the Perl Monks concerning the following question:

I have several classes that all have a common attribute, so I've created a Role to define this attribute.

All of these classes also ALL "use" the same batch of modules.

Is there anything wrong with "using" all these modules in my Role so they're all shared? and so neaten up/shorten my code a bit?

Even to the point of putting "use Data::Dumper" in the Role so I know Dumper() is always available.

Cheers

Replies are listed 'Best First'.
Re: Moose Role to include Use statements
by tilly (Archbishop) on Feb 21, 2011 at 15:50 UTC
    Avoiding typing by stuffing things into the most convenient corner without regard to what it is officially for is a fast road to a bad design. If the things in question fit into the role, then load as many as you want. If they are not logically part of the role, don't do this.

    However I would not object to creating a new module explicitly to give you all of the utility stuff you want. Name it something like StandardModules and use that instead. That will make it more obvious to the next person where you might be getting random stuff from. (But be very careful about putting things there, because they are going to pollute every namespace.)

      Ahhh true, we're being strict about what is allowed in this module.

      One included module with imported method didn't work when in the Role file anyway so had to abort that approach, and you're right, only things related to that Role should be in there anyway.

      Was just looking for the most-Moose way of doing it.

        One included module with imported method didn't work when in the Role file anyway so had to abort that approach

        This is because Moose recognizes the difference between an imported function and a method. That and roles don't have an import method (and never should IMO anyway).

        -stvn
Re: Moose Role to include Use statements
by stvn (Monsignor) on Feb 21, 2011 at 18:13 UTC

    I agree with tilly that abusing this approach is likely to end badly. The way I tend to handle these situations is to apply the following rules:

    • If the role uses the module as a type (an attribute isa "Foo") then I will load that module in the role. This assures me that the correct Moose type for "Foo" is loaded and the role is using it.
    • If the role uses the module, like a dump method using Data::Dumper then I will load the module in the role (although if the method is not going to be called often, I will sometimes load it with require or Class::MOP::load_class)
    • And lastly, to continue on tillys theme, if it does not fall into the above rules and is just something I know I will need often, I will sometimes write a MyProject::Util module which imports common stuff as well as exports (sometimes wrapped) version of useful functions from other modules. I have been liking this approach a lot lately because it allows me to (somewhat) painlessly swap implementations if I need too.

    -stvn