Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling

Simple question about namespaces

by woland99 (Beadle)
on Feb 27, 2014 at 15:07 UTC ( #1076409=perlquestion: print w/replies, xml ) Need Help??
woland99 has asked for the wisdom of the Perl Monks concerning the following question:

Hi - it is very simple question but for some reason I never had to face this issue before so I do not know enough about packages and namespaces.

I have a script and another file that defines set of subroutines Inside I have "require;".

Now letsay that I read in command line options in file and I want subroutines defined in to be able to see values of those options. I could pass them as parameter to a subroutine but there must be less clumsy way.

TIA for any pointer.

Replies are listed 'Best First'.
Re: Simple question about namespaces
by SimonPratt (Friar) on Feb 27, 2014 at 16:05 UTC

    Probably the easiest way is to shift all those sub routines back into the main script and have the required variables declared at the base script level (rather than within any sub-routines). ie:

    use strict; my $var1 = 'foo'; my $var2 = 'bar'; subRoutineA(); sub subRoutineA { print "\$var1: $var1\n\$var2: $var2\n"; }

    Alternatively, you could look into re-writing your scripts in an OO fashion and simply assign the required variables to the objects that you want to run the sub routines for

      I do agree with you about OO approach. Maybe at some point I will rewrite those scripts. But I cannot split - it is being used by 20 other scripts and it would be maintenance nuisance to have to adjust those subroutines in 20 different places. For now I defined a subroutine in specifically for setting variables in that file - and I call it in with command line options - not the prettiest solution but works.
Re: Simple question about namespaces
by Eily (Prior) on Feb 27, 2014 at 16:27 UTC

    If you have package variables in either of the two packages, the other will be able to read or write on them. For exemple you could have in : $SUBS::option = getOption(); and if you declare our $option in the package SUBS, it will be the same variable.

    If neither files have a package statement, then all variables declared by our will be in package Main, a variable declared our $option in one file will be the same as our $option in the other.

    If you feel that messing around with another package's variables isn't clean enough, you could write accessor subs to get and set them.

Re: Simple question about namespaces
by Laurent_R (Canon) on Feb 27, 2014 at 22:19 UTC

    I do not know if it will be useful in your case, but this is something I did a few years ago (I would probably do it slightly differently nowadays, but it worked and is still working). I created a module to simplify access to a low-level API to an application database, with higher level functions hiding from the user the long and complicated succession of calls to the API for any action on the database.

    Besides this simplification of the function calls, I also wanted to simplify the list of arguments passed to each function called. Many of these arguments were just the same throughout the program: database schema ID, connection ID, transaction ID, error buffer ID, etc. What I did was to create a lexical hash global to the module. And I had an init_connection function that used a hashref to populate the hash. Then, any other function within the module could use a ref to the same hash to retrieve the values it needed. Because of the refs to this hash, the hash became a persistent object within the module, even though no OO syntax was needed to do it. The module as a whole acted as a closure in which each function could access to the hash elements it needed.

    Two of hash elements were passed by the main program to the init function, the other were calculated within the init function, and then they were all stored in the hash for further use by all the other functions of the module, so that the main program did not have to worry about all these persistent parameters, making the module's functions calling syntax much simpler.

    Going further in the same direction and forgetting about the specific case I was talking about, this is how you could possibly make one variable persistent in a module and create an accessor and a mutator to it, without having to change your syntax to OO.

    my $get_val_ref; my $set_val_ref = sub { my $val = shift; return sub { return $val ; }; }; sub init { $get_val_ref = $set_val_ref->(shift); } sub read_val { return $get_val_ref->(); }
    (In case this is not clear, init and read_val are the functions exported by the module to the main program.)

    The code above is simplified to real bare bones (only one variable to be used and kept from one call to the next, etc.), but it works. Basically, change the variable passed to init to an array, a list or a hash, make the other changes needed in that case, and you are set up.

    I hope this is clear and this helps. I tried to make this post as short as possible and still giving the clues I wanted to give, please ask if you think that this might give you an interesting lead but that my explanbations were too terse or otherwise not clear.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1076409]
Approved by marto
and the monastery is silent...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (6)
As of 2018-06-21 11:23 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (118 votes). Check out past polls.