In my code base, I have several variables that "live" in the main namespace and various modules I utilize can expect to always find in main (for example, $main::author is a reference to a hash about the user, $main::dbh is the open database handle, $main::loader is an object of a core utility class and $main::FORM has the processed QUERY_STRING). E.g. when the program starts up:
$main::author = &getAuthor;
$main::loader = SAFARI::Loader->new;
use SAFARI::View;
my $view = SAFARI::View->new;
$view->output;
And then when I'm in SAFARI::View::output, I can call on those core variables, e.g.:
# Display user name:
$output .= 'Hello, ' . $main::author->{'fullName'} . '! Welcome!';
The problem: when the code is running in a threaded environment, one thread may need a different $loader object or have a different $author logged in than the other thread. More pressingly still, each thread has, of course, a different database handle.
I know I could pass along the core information when creating objects such as View by adding parameters it takes. But that means every type of object that presently can just reference these items in the main namespace must have a lengthy list of parameters instead. I'm trying to think of the most efficient and "safe" way to solve this problem.
I've considered creating a hash reference that has all the different bits in it within each thread, e.g. $common that has $common->{'FORM'}, $common->{'loader'}, $common->{'author'}, etc., and then pass those as a single argument to each object:
my $common = #Logic to set up this combination of bits for this particular thread.
my $view = SAFARI::View->new({ 'common' => $common });
my $article = SAFARI::Article->new({ 'common' => $common });
my $category = SAFARI::Category->new({ 'common' => $common });
That's not too tedious, but it still seems inefficient; it'd be preferable if the "environment" of just that thread could contain something that object within in it could access. As far as I can tell, declaring our $common within the subroutine that is run by the thread would do this and any objects created within that subroutine would have access to that variable. Is there any harm in this approach?
It seems like it would be cleaner to have these items in some sort of namespace, but if I refer to, say, $SAFARI::common, that name space would reach across threads just like main does. Would having $SAFARI::common but then declaring a local variant of it in each thread be reasonable?
Is there a "best practice" for what I'm trying to do? It's going to take some significant reworking of code to fix this one way or another, so I'd really like to get it "right."