Subverting case insensitivity for module names under Mac HFS

Ash Berlin ash_cpan at firemirror.com
Mon Jun 23 11:07:16 BST 2008


On 23 Jun 2008, at 11:52, Andy Wardley wrote:

> I'm trying to write some code that will automagically load plugin  
> modules on
> demand but I'm being thwarted by the case insensitivity of Apple's  
> HFS.
>
> Case insensitivity is a Good Thing in this case.  I would like a  
> user to be
> able to write:
>
>  [% USE wibble %]
>
> and have TT figure out that it needs to load the  
> Template::Plugin::Wibble
> module.  To make this Just Work[tm],  I thought it was simple case  
> of trying
> a few different capitalisations of the request module tacked onto my  
> base
> name:
>
>  * the name exactly as specified, e.g. FooBar ==>  
> Template::Plugin::FooBar
>  * the capitalised name, e.g. wibble => Template::Plugin::Wibble
>  * the upper case name, e.g. url => Template::Plugin::URL
>
> The code looks something like this:
>
>  sub load_plugin {
>    my ($self, $name) = @_;
>    my $bases = $self->plugin_base;		  # e.g. ['Template::Plugin']
>    my @names = ($name, ucfirst $name, uc $name); # e.g. foo, Foo, FOO
>    my $module;
>
>    foreach my $base (@$bases) {
>        foreach my $name (@names) {
>            $module = $base . '::' . $name;
>            return $module if UTILS->maybe_load_module($module);
>        }
>    }
>    return $self->error_msg( not_found => plugin => $name );
>  }
>
> So far so good.  The load_plugin() module returns the name of the  
> module
> that successfully loaded so we can write this:
>
>  my $class = $self->load_plugin($name);
>  $plugin = $class->new($config);
>
> Except that Apple's brain-dead HFS treats filenames case  
> insensitively.  It
> will merrily load Template::Plugin::URL if you ask for  
> Template::Plugin::url
> without so much as raising an eyebrow.  The problem is that Perl's  
> classnames
> are case *sensitive*, so the subsequent new() call will fail:
>
>  $class->new($config)      # ===> Template::Plugin::url->new()    #  
> FAIL!
>
> Has anyone come across this before and found an easy and/or elegant  
> way to
> work around it?  The only approach that comes to mind is to let the  
> module
> get loaded and then do some symbol table inspection to figure out  
> what the
> class name really is.  But that requires some messy OS detection and  
> smells
> a bit like apple-scented camel droppings to me.  Anyone got any  
> better ideas?
>
> The TT2 approach is to use an explicit table mapping lower case  
> names to their
> correct-case equivalents.  However, that only works for the core  
> plugins and
> doesn't include 3rd party plugin modules that may get installed later.
>
> Cheers
> A


You could maybe try mutley's Module::Pluggable(::Object) which ISTR  
does some of that for you. 


More information about the london.pm mailing list