hmonroe has asked for the wisdom of the Perl Monks concerning the following question:
|
|---|
| Replies are listed 'Best First'. | |||
|---|---|---|---|
|
Re: Accessing hash from within module
by Jenda (Abbot) on Feb 11, 2012 at 23:20 UTC | |||
Either once execute
or see Data::Alias Jenda | [reply] [d/l] | ||
|
Re: Accessing hash from within module
by BrowserUk (Patriarch) on Feb 12, 2012 at 01:12 UTC | |||
As an extension of Jenda's post. Instead of making the entire %lglobal hash visible, just cherry pick the bits of it each module needs:
And you can scope the visibility to exactly the packages, subroutines or just blocks where you need it, giving effectively lexically scoped access to your global data. It's one of Perl's most underrated features. With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] | ||
|
Re: Accessing hash from within module
by bart (Canon) on Feb 12, 2012 at 02:07 UTC | |||
That's actually do the same thing as Jenda's code snippets, but it looks just a bit less hacky. See Exporter for one way to implement it. You could also think of declaring the global variables in a dedicated module and use it in any module that requires access to them. Also note that you can use "::" as short for "main::". So you could just spell it as %::lglobal (and $::lglobal{$key}), which doesn't look to bad to me. You could event think of the "::" prefix as hungarian notation, so it could even work out for the better. | [reply] [d/l] [select] | ||
|
Re: Accessing hash from within module
by Xiong (Hermit) on Feb 12, 2012 at 07:18 UTC | |||
There are many workable approaches and you've already seen several; I'd like to offer another. I hesitate to call it a true object-oriented approach. What I'm doing here is suborning OO techniques to manage what I call a pseudo-global football. This is almost as evil as global variables; just a bit less so. Code such as $f->{barky} is only marginally more complex than a lexical $barky (and it should be, at least a little, since the football goes all over the field). Besides new() and init() you can write additional methods that deal primarily with the football; with the extra payoff that the calling convention is quite clean. Otherwise, you can pass the football around to almost anything, almost anywhere:
In the following demo, I've put the OO::Module class in the same file as the main script. Don't do that in real life; make a real module and put it in /lib. While you're at it, change identifiers to match your project's needs.
I'm not the guy you kill, I'm the guy you buy. —Michael Clayton
| [reply] [d/l] [select] | ||
by BrowserUk (Patriarch) on Feb 12, 2012 at 09:10 UTC | |||
This is almost as evil as global variables; just a bit less so. The real trouble with this OO route -- besides that it derives no true benefit from the costs of the OO -- is the clumsy syntax. Somewhere in your OO-football wrapped global, there is an array that needs to be iterated and its contents accessed:
For contrast, compare with:
With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice. -- The problem with OO; is not the OO, but ooholes that use it.
| [reply] [d/l] [select] | ||
|
Re: Accessing hash from within module
by flexvault (Monsignor) on Feb 12, 2012 at 09:40 UTC | |||
hmonroe, I have a 20,000+ line package with about 6 modules, and I use 'our' in parent that forks copies of itself once all global data has been initialized. I'm sure this is just another way of looking at the problem, but it does work for forked copies, so I'm sure it will work for all modules sharing one address space. The sample code is just a skeleton. parent code:
If your package is running as a single user, you don't have to lock the parent globals, but you must lock them if more than one module needs access to the global data. When the children want to get or update global data:
If you scope each module with a separate pair of brackets {}, and you are of course running with 'strict' and 'warnings', sometimes I get an error that I need to define a global. I just add the 'our ...' after the top '{' and it covers the entire module. It doesn't seem to happen as much as in the past, but if you see it just add the our in scope. Good Luck! "Well done is better than well said." - Benjamin Franklin | [reply] [d/l] [select] | ||