Re: Location of 'use' statements (tye)
by tye (Sage) 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 | [reply] [d/l] |
|
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. | [reply] [d/l] |
|
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.
| [reply] [d/l] |
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. | [reply] [d/l] [select] |
|
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
| [reply] |
|
| [reply] [d/l] |
|
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.
| [reply] [d/l] |
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.) | [reply] |
|
(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...
| [reply] [d/l] |
|
| [reply] |
|
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 |
| [reply] |
|
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 | [reply] [d/l] |
|
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...
| [reply] [d/l] [select] |
|
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. | [reply] [d/l] [select] |
|
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.
|
| [reply] |
Re: Location of 'use' statements
by adrianh (Chancellor) on Apr 18, 2003 at 21:42 UTC
|
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';
| [reply] [d/l] |
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.
| [reply] [d/l] [select] |
|
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).
| [reply] [d/l] [select] |
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 | [reply] [d/l] |
|
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.
| [reply] [d/l] [select] |