|The stupid question is the question not asked|
A deceptively simple question.
One piece of advice, before I suggest an approach: using a massively complicated config module that can do all of this is probably less useful than using a simple one and having some wrappers that cause the specific behavior you want on your system.
I suggest an OO API more like this:
Why an OO API? Because it avoids issues with re-using globals in persistent environments. What if you want to use config variables for more than one app in a single script (or handle requests for multiple apps in one mod_perl process)? You can take care to reset your globals, etc., but it's a pain.
Using an OO API means you have to deal with getting the config object frequently, but it should be pretty fast if you keep the parsed files in memory.
In terms of how to set up your actual config files, I'd suggest either having multiple files (e.g. system.conf, app1.conf, app2.conf) and merging them as hashes in memory (so app1.conf overrides system.conf when project eq 'app1') or using a config module with built-in support for overrides. We currenctly use Config::ApacheFormat, which lets you do things like this:
This will give you a different value for DBPassword depending on the current setting of App. There are other modules that do this too, and of course a simple Perl config does this beautifully.
Where do the smarts about concatenating paths based on projects go? In your config class, which will look at the parsed config data and figure out the answer when you call a method that needs it.
I don't think your session question makes sense here. Sessions are not config data. There's no reason they should use the same mechanism. I suggest making that a separate question with more information. I can't tell what the problem is from what you've said so far.