in reply to Design pattern factory : use lib issue on lib directory

Hi CraigWalker,

I'm not sure I understand your intent in the second example. Are you trying to relocate the class Greet::Repeat into the lib/ subdirectory, or do you actually want to rename the Greet::Repeat class to lib::Repeat, as Eily and Corion have pointed out?

If it's the former, and you want to follow the normal Perl convention of class and module naming, that means you'll have a file lib/Greet/Repeat.pm that contains the Greet::Repeat class. If so, then all you need to do to make your first piece of example code work is change the use lib statement to use lib './lib';. lib will prepend that path to @INC, so when you tell require to load the file Greet/Repeat.pm, it will look for ./lib/Greet/Repeat.pm first.

Also, the use lib './Greet'; you've got in the first code example actually doesn't help you if the file is named Greet/Repeat.pm - require will first look for ./Greet/Greet/Repeat.pm, which it doesn't find, then it looks through the rest of @INC. The first piece of example code works because the current directory . is in @INC by default. I think this can vary, but in my case . is last in @INC, so that perl actually looks through all the other @INC directories for a file named Greet/Repeat.pm first, which might not be what you want either. And AFAIK there are cases where the current directory isn't even in @INC, so that the script would fail there.

Similarly, if your intent really was to rename Greet::Repeat to lib::Repeat, then the use lib './lib'; in your second code example is also not necessary, since you've already added that path to the filename in my $location = "lib/$requested_type.pm";.

In any case, I recommend that you don't rely on the current directory . as much. It's acceptable for initial testing, but in production I'd strongly recommend you use absolute paths for lib, or you use a different way of setting up @INC properly. Sometimes FindBin can help you (but it's not perfect, so be careful and test it first). (For example, if I've got a script I call from the command line and it needs a module that I know will always be in the same directory as the script, I'll sometimes write use FindBin; use lib $FindBin::Bin; use ModuleName;.)

Hope this helps,
-- Hauke D