http://www.perlmonks.org?node_id=345472

It is common knowledge that module names are case-sensitive. This makes sense, because package names are case-sensitive.

It is also widely known that modules are stored in a directory structure that mirrors their names, such that Beverage::Carbonated::CO2 is stored in lib/Beverage/Carbonated/CO2.pm.

It is less widely known that some file systems are case-insensitive, notably those used by the MacOS (including MacOS X) and some configurations of Windows.

The result of these three facts is that Beverage::Carbonated::CO2 and Beverage::Carbonated::Co2 are different modules, with different packages, but cannot be easily installed at the same time on some OSes.

"So what?" you ask. "Surely there aren't any CPAN modules whose names differ only in capitalization!"

Unfortunately, there are.

As of 12 April 2004, 44 sets of CPAN modules had names that differed only in capitalization. The full list appears at the end of my post, along with the program that generated it.

I first realized this problem when I was checking to see if I had the latest version of Pod::HTML. Um, I mean, Pod::Html. The latter is included with the core Perl distribution, the former is part of the PodSimplify distribution. The problem is, the two are different modules, with different interfaces. If I had actually installed Pod::HTML, it would have overwritten Pod::Html, meaning that pod2html and any script that used Pod::Html would no longer work, and I would have a heck of a time figuring out why.

The lesson is, make sure your module's name differs from other modules' names in more than just capitalization, and be careful about capitalization when you're installing a module on a case-insensitive file system.

perlport says:

Do not have two files or directories of the same name with different case, like test.pl and Test.pl, as many platforms have case-insensitive (or at least case-forgiving) filenames.
It might be a good idea to add something about module names after that.

Please note that this is not a flame against anyone who has written a module whose name differs from another module's by only case. It's difficult to take into account the peculiarities of other platforms when you're developing, especially when you can't test on those platforms.

(And yes, I am aware that there can be several different lib directories in which modules can be installed, but as long as one of them is always used for module installation, the problem with overwriting modules still applies.)

The list of modules and the program used to generate the list appear below:

44 sets of duplicates:
  • Apache::Test | Apache::test
  • base | Base
  • Bio::Das::Request::dsn | Bio::Das::Request::Dsn
  • Bio::SeqIO::EMBL | Bio::SeqIO::embl
  • Bio::SeqIO::Fasta | Bio::SeqIO::fasta
  • Bio::SeqIO::GCG | Bio::SeqIO::gcg
  • Bio::SeqIO::Raw | Bio::SeqIO::raw
  • Class::PObject::Driver::DB_File | Class::PObject::Driver::db_file
  • Crypt::SecurID | Crypt::securid
  • Crypt::TEA | Crypt::Tea
  • DES | Des
  • example | Example
  • Example1 | example1
  • FAQ::OMatic::Help | FAQ::OMatic::help
  • FAQ::OMatic::Search | FAQ::OMatic::search
  • File::Stat | File::stat
  • Finance::Shares::Momentum | Finance::Shares::momentum
  • Foo | FOO
  • Gettext | gettext
  • Graphics::PLPLOT | Graphics::PLplot
  • Inline::CPP::Grammar | Inline::CPP::grammar
  • LISP::List | Lisp::List
  • LWP::Authen::Basic | LWP::Authen::basic
  • LWP::Authen::Digest | LWP::Authen::digest
  • Math::GSL | Math::Gsl
  • Mcrypt | MCrypt
  • MP3::Tag::ID3v1 | MP3::TAG::ID3v1
  • MP3::Tag::ID3v2 | MP3::TAG::ID3v2
  • My::db | My::DB
  • Net::LDAP::Control::Sort | Net::LDAP::Control::sort
  • Net::TrackBack | Net::Trackback
  • Petal::Hash::VAR | Petal::Hash::Var
  • Pod::HTML | Pod::Html
  • Pod::Rtf | Pod::RTF
  • pragmatic | Pragmatic
  • Qt | QT
  • SGI::syssgi | SGI::Syssgi
  • stem | Stem
  • swig | SWIG
  • Sys::Lastlog | SYS::lastlog
  • testcases::Base | testcases::base
  • types | Types
  • URI | uri
  • XBase | Xbase
The above was generated with this program:
#!/usr/bin/perl -w use strict; #File below is decompressed http://perl.org/CPAN/modules/02packages.de +tails.txt.gz open(MODULES, '<', '02packages.details.txt') or die "Can't open module + info: $!"; my %all_modules; my %duplicates; my $inheader = 1; #02packages.details.txt has several header lines, th +en a blank line, then the module names. while (<MODULES>) { if ($inheader) #This technique for ignoring the header was taken f +rom { #Merlyn's MINICPAN script: http://www +.stonehenge.com/merlyn/LinuxMag/col42.html $inheader = 0 unless /\S/; next; } my ($module, undef, undef ) = split; if(exists $all_modules{lc $module}) { push @{$all_modules{lc $module}}, $module; $duplicates{lc $module} = 1; } else { $all_modules{lc $module} = [$module]; } } print scalar(keys %duplicates)." sets of duplicates:\n\n"; foreach(sort keys %duplicates) { print join ' | ', @{$all_modules{$_}}; print "\n"; }

Once it's Turing complete, everything else is just syntactic sugar.

Replies are listed 'Best First'.
Re: The Case for Sensitivity to Case-Insensitivity in Module Names
by Ovid (Cardinal) on Apr 15, 2004 at 20:45 UTC

    I actually learned this the hard way when porting some Perl written on Windows to Linux. I had no problem useing something with incorrect case, but actually relying on the class name caused things to break! This was a long time ago with ActiveState Perl. I wonder if they ever fixed that? I don't have a Windows box to test that on.

    use FOO; # but finds Foo.pm my $foo = FOO->new; # but told me I didn't load the FOO package!

    Cheers,
    Ovid

    New address of my CGI Course.

Re: The Case for Sensitivity to Case-Insensitivity in Module Names
by simonm (Vicar) on Apr 16, 2004 at 13:45 UTC
    This list would be shorter if you only examined the most recent version of each distribution.

    For example, Bio::SeqIO::Fasta is from bioperl-0.05.1 (05 Jul 1999), while Bio::SeqIO::fasta is from bioperl-1.4 (23 Dec 2003).

    Similarly, Petal::Hash::VAR is from Petal-0.64 (03 Sep 2002), while Petal::Hash::Var is from Petal-2.05 (05 Apr 2004).

    In both cases, those modules are only used internally, so no public interface is broken by the case change.

    Some of the other cases are still relevant -- for example, Stem and stem are from two different distributions.

    If you wanted to make sure this didn't happen again, the PAUSE indexer could be patched to do case-folded comparisons so that module authors would be warned of this kind of conflict.

      If you wanted to make sure this didn't happen again, the PAUSE indexer could be patched to do case-folded comparisons so that module authors would be warned of this kind of conflict.

      Yes, I'm unsure exactly what to do about this. While I could see warning future module authors about it, the problem is that there are already modules whose names differ already in case. You couldn't easily prevent uploads of modules whose names case-insensitively conflict with other modules unless you wanted to prevent all of the authors of the modules that already exist from uploading new versions. It would probably be too heavy-handed to make a bunch of people change their modules' names.

      I guess you could prevent people from uploading modules whose names have never been used before but conflict with others case-insensitively, though. Still, maybe just warning authors is the best solution.


      Once it's Turing complete, everything else is just syntactic sugar.
Re: The Case for Sensitivity to Case-Insensitivity in Module Names
by Steve_p (Priest) on Apr 16, 2004 at 14:03 UTC

    This isn't limited to modules, however. Many an OS X user here probably remembers their first install of LWP. LWP creates a script named HEAD which simply does an HTTP HEAD request. Unfortunately, since Mac OS X has a case insensative file system, HEAD would overwrite head in /usr/bin. I know it took me a while to realize what was going on.

Re: The Case for Sensitivity to Case-Insensitivity in Module Names
by rinceWind (Monsignor) on Apr 16, 2004 at 09:42 UTC
    I am going to to cross post this to the vmsperl list, as VMS is an O/S that's not even case preserving let alone case sensitive.

    --
    I'm Not Just Another Perl Hacker

Re: The Case for Sensitivity to Case-Insensitivity in Module Names
by jacques (Priest) on Apr 21, 2004 at 20:02 UTC
    You might be interested in my win module, which addresses this issue on Win32 systems.