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

nagalenoj has asked for the wisdom of the Perl Monks concerning the following question:

Hope, this doesn't be a vague question, let me explain what is needed for me to my best..

I've to write a program, where I need to share some resources(data) across most of the packages used in my script.

For example, objects for logging and DB module is needed in most of the packages, I need to write a report at the end of the flow about the entire execution. So, I need to fetch/insert/update data in the report in between the packages.

What is the better way to share data among all the packages in a script?I know it's not good a idea to use global variables and global data structures.

Replies are listed 'Best First'.
Re: Share data among different packages
by ELISHEVA (Prior) on Dec 22, 2010 at 13:59 UTC

    This is a perfect job for a combination of modules and objects. Usually when there is a lot of data that needs to be shared, it is best to encapulate all of it into a single controller class that generates all the necessary objects, manages relationships between them, launches supplemental scripts as needed and so on.

    Your main launch script will then be quite simple. It just takes in command line parameters, parses them and sets up a single root object.

    Global variables, in and of themselves are not bad, but a massive number of them, especially in the main namespace often signals a design problem in your code. It suggests that you haven't thought through the relationships between the global variables very carefully.

    Are they constants? If so, are you cluttering up the global namespace with constant names and preventing your submodules from using those names for their own purposes? Perhaps it would be wiser to place the variables in a package and declare them as our variables. That way they still can be read by all your programs but you don't clutter up the module namespace.

    If they are not constants, do they all work in concert? If so, why aren't they encapsualted in an object? If not, why is the relationship between them and why do you need so many?

    There may be good reasons for making that single root object a global variable, especially if you declare the variable as an our variable in a package other than main. For example, many application API's have a single $myApp or $SOME_PACKAGE::approot variable. Any script that needs to interact with the application simply makes calls on the $myApp object.

    Are you familiar with perltoot? If you are new to objects and classes in Perl, that might be a good place to start.

Re: Share data among different packages
by JavaFan (Canon) on Dec 22, 2010 at 14:01 UTC
    I know it's not good a idea to use global variables and global data structures.
    That's the disadvantage of sound-bites. They evolve into dogmas, and people take it for gospel.

    It's a bad idea to use global variables and global data structures for local use. But if you want information to be accessible globally, there's nothing wrong with global variables. ("Singleton solution" make use of global variables as well - it's just a global coderef instead of global scalar/array/hash). The alternative is to set up your data locally, and pass references to it to every subroutine that either needs it, or calls (directly or indirectly) a subroutine that needs it.

Re: Share data among different packages
by Anonymous Monk on Dec 22, 2010 at 13:49 UTC
    Use a special global, called a singleton, its what everyone does, for example, see Log::Log4perl Why Log::Log4perl->get_logger and not Log::Log4perl->new?
Re: Share data among different packages
by happy.barney (Friar) on Dec 22, 2010 at 13:48 UTC
    use base class or special config class/object.