Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Location of 'use' statements

by djantzen (Priest)
on Apr 18, 2003 at 18:55 UTC ( #251507=perlquestion: print w/ replies, xml ) Need Help??
djantzen has asked for the wisdom of the Perl Monks concerning the following question:

I am in inner turmoil about my placement of use statements in modules, and I wonder if some kind monks have any opinions to share. The goal is some kind of conceptual purity, and I've tried a variety of approaches but I'm never happy with one for longer than a module or two. Should the statements come before or after the package statement? Organized alphabetically, or by importance, or by type (pragma, module, base module)?

Stuff I've tried:

  1. package statement, then alphabetical listing like:
    package Foobar; use constant STR => 'quack'; use Data::Dumper; use Quux; use strict; use warnings;

  2. package statement, pragmas, modules, base modules:
    package Foobar; use constant STR => 'quack'; use strict; use warnings; use Data::Dumper; use base 'Quux';

  3. "importance":
    package Foobar; use base 'Quux'; use constant STR => 'quack'; use strict; use warnings; use Data::Dumper;

  4. (My current thoughts) Order by non-package-specific pragmas/modules, package statement, package-specific pragmas/modules.
    use strict; use warnings; use Blarney; package Foobar; use constant STR => 'quack'; use Data::Dumper; use base 'Quux';

The last one I think is the most precise, with a distinction between stuff that needs to be imported into the package Foobar vs. stuff that can exist happily in package main. But it may also be more confusing to someone just looking at the code. {sigh} Thoughts? TIA, djantzen


"The dead do not recognize context" -- Kai, Lexx

Comment on Location of 'use' statements
Select or Download Code
Re: Location of 'use' statements
by perrin (Chancellor) on Apr 18, 2003 at 19:10 UTC
    Number 3 of course! Putting anything before your package statement is just wierd, and pragmas and inheritance are more important than external libraries. I would consider "use constant" a totally different kind of thing and put it after everything else with a blank line above it. (Actually, I would just not use that annoying thing, but that's a different story.)

      (Actually, I would just not use that annoying thing, but that's a different story.)

      I for one would like to hear that story. I don't use them often, primarily for real constants (like OS constants and the like) and things like DEBUG. But I'm curious if theres some trap or zap that I havent quite fallen into that I aught to know about?

      ---
      demerphq

      <Elian> And I do take a kind of perverse pleasure in having an OO assembly language...
        The problem with "use constant" is that the constants are implemented as subroutines. This means that they break (silently) if you try to use them as hash keys, in double-quoted strings, or any other place where barewords are not interpreted as sub calls.

        If you use global variables instead, everyone knows what they are and you avoid these bugs which tend to catch every user of constant at least once.

Re: Location of 'use' statements
by Beatnik (Parson) on Apr 18, 2003 at 19:18 UTC
    You do realize the order in which you use might be important when importing/poisining your namespace. The last modules used will overwrite any other subroutines that might be import. I think at some point in history, LWP::Simple and CGI clashed at something like that.

    Greetz
    Beatnik
    ... I'm belgian but I don't play one on TV.

      You mean if two modules export functions with the same name? In that case you'll have problems no matter what the order though, right? Fortunately I haven't encountered that problem before myself, but the possibility is just one more reason to use warnings. :^)


      "The dead do not recognize context" -- Kai, Lexx

        I'm quibbling over whether to be a fan of use warnings FATAL => 'all'; which would ensure you didn't do that by accident.

        Ofcourse you are in trouble but the order in which use is used determines which function is actually used.

        Greetz
        Beatnik
        ... I'm belgian but I don't play one on TV.
Re: Location of 'use' statements
by pfaut (Priest) on Apr 18, 2003 at 19:20 UTC

    Since many modules export into the namespace of the module they are used by, you should put your 'use' statements after your package declaration. If you have multiple packages defined in a single file, you may need multiple 'use' statements for the same modules.

    90% of every Perl application is already written.
    dragonchild

      Yep, Data::Dumper for example will complain (under -w) about printing to an unopened file handle if you say

      use Data::Dumper; package Foobar; my $quux = {} print Dumper $quux;

      The idea between the fourth approach is to separate those things must be imported into the package itself, versus those that can be left apart.


      "The dead do not recognize context" -- Kai, Lexx

        Yep, Data::Dumper for example will complain (under -w) about printing to an unopened file handle if you say

        Actually its perl that complains here. The warning is provided because perl reads

        print Dumper $quux;

        as

        use IO::File; Dumper->print($quux);

        when 'Dumper' is an unknown bareword. Personally I always disambiguate print statements in some way just because ive been bitten a few times.

        Incidentally in this case its not much harder (and often desirable) to replace that with

        print Data::Dumper->new([$quux],['quux'])->Dump(),"\n";

        I say desirable, and use the long winded ->new() form because now we can easily add stuff in the middle:

        # we have large cyclic structures: disable pretty indent, enable purit +y mode. print Data::Dumper->new([$quux],['quux'])->Purity(1)->Indent(1)->Dump( +),"\n";

        ---
        demerphq

        <Elian> And I do take a kind of perverse pleasure in having an OO assembly language...
Re: Location of 'use' statements
by rir (Vicar) on Apr 18, 2003 at 19:25 UTC
    Number three until it is unwieldy.

    Unwieldy -- having more than one package in a file. Having so many uses that some alphabetization is necessary.

    I'd put strict and warnings separate, and constant separate again.

    Update: It's because pragmas go into scopes and modules into namespaces.

      When it starts becoming unwieldy, you know it's time to break it up.


      MJD says you can't just make shit up and expect the computer to know what you mean, retardo!
      I run a Win32 PPM repository for perl 5.6x+5.8x. I take requests.
      ** The Third rule of perl club is a statement of fact: pod is sexy.

Re: Location of 'use' statements (tye)
by tye (Cardinal) on Apr 18, 2003 at 20:55 UTC
    package FooBar; ## Always used: use strict; use warnings; ## Other modules: require Some::OO::Module; use Some::Function::Module qw( Func1 Func2 ); ## Setup of this module: use base 'Quux'; use vars qw( $VERSION @EXPORT_OK ); $VERSION= 1.001; @EXPORT_OK= qw( ... ); ## Globals: use vars qw( $Master ); $Master= ...; use constant _IdNo => 0; use constant _Name => 1; use constant _Pos => 2; # Gee, we need "use enum" (:

    with a general tendency to put shorter items before longer items first.

                    - tye
      This is very close to what I do. I think of strict and warnings as part of an extended shebang line. Exporter is ugly so I avoid it wherever possible; though when I use it, I tend not to treat it and its globals specially. Finally, I reserve require solely for deferred loading of modules. So I arrive at a layout like this:
      #!/usr/bin/perl use strict; use warnings; package FooBar; use Some::OO::Module (); use Some::Function::Module qw( Func1 Func2 ); use base 'Quux'; use vars qw($VERSION); $VERSION= 1.001; use constant _IdNo => 0; use constant _Name => 1; use constant _Pos => 2;

      Makeshifts last the longest.

      This is pretty much what I do, with the following differences:
      package Blah; use strict; =HEAD1 NAME ... =cut BEGIN { # If I have one use XXX; # as required here } # pragma level 'use's use vars qw(...); # Core modules # CPAN modules # local modules # globals and initializing assignments # actual code at this point
      I personally prefer the POD at the top, since it encourages me to write it first and update it first. Keeping it in front of my face as the first thing I see when the editor opens the file helps keep that positive guilty feeling of "you didn't update the POD, did you?" going, with the result that I actually do update it.
Re: Location of 'use' statements
by adrianh (Chancellor) on Apr 18, 2003 at 21:42 UTC

    My preference is for:

    package FooBar; use base qw(Foo); # because I like the class hierarchy to be obviou +s # always have use strict; use warnings; # core or CPAN modules use File::Find; use DBI; # application specific modules use MyApp::Configuration; use MyApp::Template; # module specific stuff use constant DEBUG => 0; our $VERSION = '0.02';
Re: Location of 'use' statements
by demerphq (Chancellor) on Apr 19, 2003 at 11:03 UTC

    I work with MS Source-Safe (some may say thats unfortunate ;-) whose source contol keyword expansion often doesnt play nicely with perl unless you jump through hoops (as the keywords start with a dollar sign, ie $Log gets translated, wich aint cool if youve used it as a vairable name /grr). This means that I need to put certain source control related stuff as close to the top as possible.

    Other than that my preferences are fairly similar to tye and adrianh, probably the most notable difference is that I put pragmas like strict and warnings after my modules, I do this because as they are lexically scoped they have no effect on the contents of the used modules, and to me doing it this way makes this more clear, especially to a potentially inexperienced maintenance coder.

    I also usually add a special block at the end for doing module test/development so that you can say perl Module.pm and have it self test or diagnostics or just plain old dev code.

    package Foo::Bar; #always goes at the top! ###################################################################### +########## # $Header:: /prject/name.pl 4 02/12/04 18:46 Author + $# ($VERSION) = sprintf "%d.%03d", 1, ' $Revision:: 4 $' =~ /::\ +s+(\S+)/;# # $NoKeywords:: + $# ###################################################################### +########## use base qw/Some::Module/; # 'cause the relationship is important use Essential::CPAN::Modules; use Essential::NONCPAN::Modules; use Non::Essential::Modules; (ie debugging and the like) # I always use strict; use warnings; use warnings::register; # and maybe some other pragmas too use constant here=>1; use vars qw($Here $Should $We $Use $Them); BEGIN { # Any module specific initialization type stuff that must happen firs +t. # if vars qw() have been used and they need defaults they get them he +re. $Here||="A default value"; } sub routines_get_defined_here { } unless (caller) { # module test/development code goes here. This is useful becuase you + can then # say perl module.pm # and have it self test or devtest itself. } 1; package Virtual::Utility::Namespaces::Go::Here; 1; __END__ =pod And Pod goes here =cut


    ---
    demerphq

    <Elian> And I do take a kind of perverse pleasure in having an OO assembly language...

    • Update:  
    Im a huge fan of warnings::register. I use it alot and try to avoid "normal" warnings, replacing them with warnings::warnif.


      I put pragmas like strict and warnings after my modules, I do this because as they are lexically scoped they have no effect on the contents of the used modules, and to me doing it this way makes this more clear, especially to a potentially inexperienced maintenance coder.

      use Foo::Bar quux => ${'VERSION'}; use strict;
      An extremely bad example, of course, but while playing with Exporter::Tidy, I noticed that when a use statement gets more complex, you really do want strict active there:
      package Example; use Exporter::Tidy _map => { foo => \$foo }; use strict; my $foo; # silently making $Example::foo exportable
      With strict, I would have found out my mistake of using $foo before it has been declared immediately:
      package Example; use strict; use Exporter::Tidy _map => { foo => \$foo }; my $foo; # Global symbol "$foo" requires explicit package name ...

      Clean solution: foo => \my $foo

      Juerd
      - http://juerd.nl/
      - spamcollector_perlmonks@juerd.nl (do not use).
      

Re: Location of 'use' statements
by dpuu (Chaplain) on Apr 19, 2003 at 20:19 UTC
    I like to keeps things local, where possible. For example, if Data::Dumper is only used by one sub in my package, then I'd include it within the scope of that subroutine. Unfortunately, Perl5 can't honour that scoping (subs are package-scoped, not lexical), but it feels nicer to have the use close to where the symbols are used. --Dave

      Obviously if it works for you it's a good thing :-)

      However, I've had to maintain code in this style and it's been a complete pain. In particular:

      • You have to scan the whole module to find out what modules are being used.
      • It can lead to confusion when you add a subroutine that clashes with an imported subroutine - since there is no global place where you can find out what subroutines have been imported.
      • You suddenly have modules being loaded at runtime if you decide to use AutoSplit - which can lead to some rather evil debuging sessions.
      • Makes refactoring harder since you have to remember to move the use around when you move the code that uses the module in question.

      In general I've found that pretending use has different scoping rules causes more problems that it solves.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (11)
As of 2014-09-19 16:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (143 votes), past polls