Perl module naming convention - perl

I have checked
On the Naming of Modules,
perldoc perlvar and
perldoc perlmod
but can not find best practices for naming modules whose name is an acronym: SMTP, ORM.
At once on CPAN both variants names are seen: SMTP and Smtp
If my new module name is an acronymthen
what would be the better name for it: My::Module::Abcd or My::Module::ABCD?

In naming convention for Perl, aside from reserved you get to choose a naming convention that can be understood among those you work with. No module that starts with keywords or reserved prefix will be accepted to CPAN or the core.
So you can either choose to adopt My::Module::Abcd or My::Module::ABCD as long as you chose to adopt one that will helping people find your module.
Alternatively, you can use an underscore in the top-level name (like My_Corp::Session or just My_Session). All categories with an underscore have also been reserved. (This is mentioned in perlmodlib, under "Select a name for the module".)
Note that both those reservations apply only to the top-level name. For example, there are CPAN modules named Time::Local and Text::CSV_XS. But Local::Time and Text_CSV::XS are reserved names and would not be accepted on CPAN.
Naming modules after your company is fine too. (Well, unless you work for some really generic sounding company.) Using the reverse domain name is probably overkill, unless you intend to distribute your modules to others. (But in that case, you should probably register a normal module name.)
You might want to take a long at How do I choose a package name for a custom Perl module that does not collide with builtin or CPAN packages names?

Related

Does %INC contain all dependencies

I'm interested in knowing which modules a script I'm working with uses (I did not write it from scratch, so I'm not sure). I know that %INC contains modules used by my script, but does it also contain modules used by those modules?
Yes, it does. Every successful require or use adds the module to %INC. (This includes optional modules if they were loaded.) Look at the pseudocode for require in its documentation.

Why are Perl modules case sensitive?

Although I haven't seen any modules with same name but with different cases, but just for curiosity, I was trying to install Log::Log4perl and during installation I misspelled it 'Perl' in place of 'perl':
% cpan -i Log::Log4Perl
Cannot install Log::Log4Perl, don't know what it is.
When I used correct name then things went well:
% cpan -i Log::Log4perl
Same names but different cases can create conflicts. Is there any specific reason behind that?
Because
use Foo::Bar;
would be ambiguous on case-sensitive file systems (Foo/Bar.pm? foo/bar.pm? FOO/BAR.pm? Foo/Bar.PM? etc), and it would require traversing the directory's contents to find the file's name. (Up to 9 directories per element of #INC would need traversing for Foo::Bar.)
In Perl, modules loaded with use translated directly onto the file system. Something such as use Log::Log4perl translates into:
BEGIN {
require 'Log/Log4perl.pm';
Log::Log4perl->import;
}
On a system that has a case sensitive file system, if the name is not exactly in the same case, it might as well not even exist. This is explained in the documentation for use and require. Different cases mean different names.
As such, when the cpan command translates a package name into a distribution, it uses the exact case you specify. The filesystem might be case insensitive, but inside Perl, the package names are still case sensitive. The literal case you enter is the one that Perl (and the cpan client) uses. If a package of that exact case isn't defined, the right things won't happen.
I consider this to be one of the major design decisions that hold Perl back and talked about it in my Frozen Perl 2011 keynote address.
Curiously, case insensitive filesystems lets you get away with it, as seen with the use seems to be case INSENSITIVE!! post on Perlmonks.

Module naming convention: Reserved prefix for internal distributions? [duplicate]

I have read the perldoc on modules, but I don't see a recommendation on naming a package so it won't collide with builtin or CPAN module/package names.
In the past, to develop a local Session.pm module, I have created a local directory using my company's name, such as:
package Company::Session;
... and Session.pm would be found in directory Company/.
But I'm just not a fan of this naming convention. I would rather name the package hierarchy closer to the functionality of the code. But that's how it's done on CPAN generally...
I feel like I am missing something fundamental. I also looked in Damian's Perl Best Practices but I may not have been looking in the right place...
Any recommendations on avoiding package namespace collisions the right way?
Update w/ Related Question: if there is a package name conflict, how does Perl choose which one to use? Thanks everyone.
The namespace Local:: has been reserved for just this purpose. No module that starts with that prefix will be accepted to CPAN or the core. Alternatively, you can use an underscore in the top-level name (like My_Corp::Session or just My_Session). All categories with an underscore have also been reserved. (This is mentioned in perlmodlib, under "Select a name for the module".)
Note that both those reservations apply only to the top-level name. For example, there are CPAN modules named Time::Local and Text::CSV_XS. But Local::Time and Text_CSV::XS are reserved names and would not be accepted on CPAN.
Naming modules after your company is fine too. (Well, unless you work for some really generic sounding company.) Using the reverse domain name is probably overkill, unless you intend to distribute your modules to others. (But in that case, you should probably register a normal module name.)
How Perl resolves a conflict:
Perl searches the directories in #INC for a module with the specified name. The first module found is the one used. So the order of directories in #INC determines which module would be used (if you have modules with the same name installed in different locations).
perl -V will report the contents of #INC (the highest-priority directories are listed first). But there are lots of ways to manipulate #INC at runtime, too.
BTW, Raku can handle multiple modules with the same name by different authors, and even use more than one in a single program. That's a different solution.
There is nothing wrong with naming your internal modules after your company; I always do this. 90% of my code ends up on CPAN, so it has "normal" names, but the internal stuff is always starts with ClientName::.
I'm sure everyone else does this too.
What's wrong with just picking a name for your package that you like and then googling "perl the-name-you-picked"?
The #INC variable contains a list of directories to in which to look for modules. It starts with the first entry and then moves on to next if it doesn't find the request module. #INC has a default value that created when perl is compiled, but you can can change it with the PERL5LIB environment variable, the lib pragma, and directly manipulating the #INC array in a BEGIN block:
#!/usr/bin/perl
BEGIN {
#INC = (); #no modules can be found
}
use strict; #error: Can't locate strict.pm in #INC (#INC contains:)
If you need the maximum level of certainty that your module name will not conflict with someone else's you can take a page from Java's book: name the module with the name of the companies domain. So if you work for Example, Inc. and their domain name is example.com, you would name your HTML parser module Com::Example::HTML::Parser or Example::Com::HTML::Parser. The benefit of the first is that if you have multiple subunits they can all have their own name space, but the modules will still sort together:
Com::Example::Biz::FindCustomers
Com::Example::IT::ParseLogs
Com::Example::QA::TestServer
but it does look odd at first.
(I know this post is old, but as I've had to sort this out in the past few months, I thought I'd weigh in)
At work we decided that 'Local::' felt too geographic. CompanyName:: had some problems for us too that aren't development related, I'll skip those, though I will say that CompanyName is long when you have to type it dozens of times.
So we settled on 'Our::'. Sure, we're not 'CPAN Safe' as there could be the day when we want to use a CPAN module with the Our:: prefix. But it feels nice.
Our::Data is our Class::DBI module
Our::App is our generic app framework that does config handling and Getopt stuff
Nice to read and nice to type.

Perl class naming convention

Let's say I create a class named Bar. The file Bar.pm starts
package Bar;
To avoid colliding with other Bar classes, I put the file in a subdirectory Foo. So now, when I use the class, I have to write
use Foo::Bar;
My question is, do I need to change the name of the class to Foo::Bar? In other words, do I need to change the first line of Bar.pm to
package Foo::Bar;
? The problem is, if I do this, I now have to refer to the class as Foo::Bar everywhere, e.g.
my $obj = Foo::Bar->new();
Foo::Bar->doClassMethod();
which is annoying (the same problem was discussed in this question), especially since I am fond of class methods.
Yes, you have to change the name of the package to exactly match that of the use.
If you think having a class name Bar might conflict with other classes named Bar then simply moving the file won't help. If your program eventually uses both Bar and Foo::Bar then both will have been loaded into the same namespace. At that point what happens to your program is anyone's guess.
If don't want to type long class names then you can use a variable to hold the name.
use My::Long::Class::Name::For::Bar;
my $bar_class = 'My::Long::Class::Name::For::Bar';
$bar_class->class_method(); # the same as My::Long::Class::Name::For::Bar->class_method()
You don't strictly need to (i.e. it's a style decision, not something the compiler enforces), but it is a good idea to follow the relevant guidelines set out in perlmod/perlnewmod to make the software easily distributable.
IOW, if long names bother you, get an editor with autocompletion.
Quoting perldoc -f require:
If EXPR is a bareword, the require assumes a ".pm" extension and
replaces "::" with "/" in the filename for you, to make it easy to
load standard modules. This form of loading of modules does not risk
altering your namespace. In other words, if you try this:
require Foo::Bar; # a splendid bareword
The require function will actually look for the "Foo/Bar.pm" file in the
directories specified in the #INC array.
So, yes, it's convention that if your module is located at $dir/Foo/Bar.pm for some $dir in #INC, then it must be called Foo::Bar.
The package Local is reserved just for this use. For example, if you create a package Bar.pm, you could call the package Local::Bar and know it won't clash with something in CPAN.
By default, #INC includes the current directory, so you could create a Local subdirectory, and then put all of your packages there. In a company, I'll divide up the Local package namespace into groups and even names of the developers. For example, I could use Local::Cm::Bar or Local::David::Bar. That way, if I decide I could use Alice's Bar class, I could simply include Local::Alice::Bar.
Yes, the standard CPAN rules state not to use your name in package namespaces, but Local packages never go into CPAN.

How do I choose a package name for a custom Perl module that does not collide with builtin or CPAN packages names?

I have read the perldoc on modules, but I don't see a recommendation on naming a package so it won't collide with builtin or CPAN module/package names.
In the past, to develop a local Session.pm module, I have created a local directory using my company's name, such as:
package Company::Session;
... and Session.pm would be found in directory Company/.
But I'm just not a fan of this naming convention. I would rather name the package hierarchy closer to the functionality of the code. But that's how it's done on CPAN generally...
I feel like I am missing something fundamental. I also looked in Damian's Perl Best Practices but I may not have been looking in the right place...
Any recommendations on avoiding package namespace collisions the right way?
Update w/ Related Question: if there is a package name conflict, how does Perl choose which one to use? Thanks everyone.
The namespace Local:: has been reserved for just this purpose. No module that starts with that prefix will be accepted to CPAN or the core. Alternatively, you can use an underscore in the top-level name (like My_Corp::Session or just My_Session). All categories with an underscore have also been reserved. (This is mentioned in perlmodlib, under "Select a name for the module".)
Note that both those reservations apply only to the top-level name. For example, there are CPAN modules named Time::Local and Text::CSV_XS. But Local::Time and Text_CSV::XS are reserved names and would not be accepted on CPAN.
Naming modules after your company is fine too. (Well, unless you work for some really generic sounding company.) Using the reverse domain name is probably overkill, unless you intend to distribute your modules to others. (But in that case, you should probably register a normal module name.)
How Perl resolves a conflict:
Perl searches the directories in #INC for a module with the specified name. The first module found is the one used. So the order of directories in #INC determines which module would be used (if you have modules with the same name installed in different locations).
perl -V will report the contents of #INC (the highest-priority directories are listed first). But there are lots of ways to manipulate #INC at runtime, too.
BTW, Raku can handle multiple modules with the same name by different authors, and even use more than one in a single program. That's a different solution.
There is nothing wrong with naming your internal modules after your company; I always do this. 90% of my code ends up on CPAN, so it has "normal" names, but the internal stuff is always starts with ClientName::.
I'm sure everyone else does this too.
What's wrong with just picking a name for your package that you like and then googling "perl the-name-you-picked"?
The #INC variable contains a list of directories to in which to look for modules. It starts with the first entry and then moves on to next if it doesn't find the request module. #INC has a default value that created when perl is compiled, but you can can change it with the PERL5LIB environment variable, the lib pragma, and directly manipulating the #INC array in a BEGIN block:
#!/usr/bin/perl
BEGIN {
#INC = (); #no modules can be found
}
use strict; #error: Can't locate strict.pm in #INC (#INC contains:)
If you need the maximum level of certainty that your module name will not conflict with someone else's you can take a page from Java's book: name the module with the name of the companies domain. So if you work for Example, Inc. and their domain name is example.com, you would name your HTML parser module Com::Example::HTML::Parser or Example::Com::HTML::Parser. The benefit of the first is that if you have multiple subunits they can all have their own name space, but the modules will still sort together:
Com::Example::Biz::FindCustomers
Com::Example::IT::ParseLogs
Com::Example::QA::TestServer
but it does look odd at first.
(I know this post is old, but as I've had to sort this out in the past few months, I thought I'd weigh in)
At work we decided that 'Local::' felt too geographic. CompanyName:: had some problems for us too that aren't development related, I'll skip those, though I will say that CompanyName is long when you have to type it dozens of times.
So we settled on 'Our::'. Sure, we're not 'CPAN Safe' as there could be the day when we want to use a CPAN module with the Our:: prefix. But it feels nice.
Our::Data is our Class::DBI module
Our::App is our generic app framework that does config handling and Getopt stuff
Nice to read and nice to type.