Re: Global or not global by davido (Bishop) on Jul 03, 2012 at 05:43 UTC |
One option is to put your data manipulation in a class (or classes), and as it is instantiated, pass a database handle to the object. Then the constructor requires that you pass a handle to it. Store it as an object attribute. If you're using something like Moose you could encapsulate your database handle in a role and mix it into classes that require access. Of course "mixins" or roles aren't unique to Moose; you could achieve similar with good old-fashioned Perl objects too.
| [reply] |
Re: Global or not global by BrowserUk (Pope) on Jul 03, 2012 at 05:48 UTC |
Log::Log4perl solves this elegantly by providing a singleton. So you can add logging whereever you want simply by calling get_logger).
How is calling my $log = Log::Log4perl->get_logger("My::MegaPackage") in every function or method: elegant?
Surely they could have fitted another couple of "log"s in there somewhere.
Maybe my $log_logger = Log::Log4perl->get_log_logger( ... )
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".
| [reply] [d/l] [select] |
|
use Log::Log4perl qw(get_logger :nowarn);
...
get_logger->info("Shit happens");
IMHO when you have decided to use Log::Log4perl then it is in the installation prerequisites.
To have a function name like 'get_logger' is unique enough for loading it in your current namespace. When Log::Log4perl is not initialized, the code doesn't hurt. So, whenever I need an additional log statement, I just insert get_logger->error("Somewhat");
That what I meant with 'elegant'. Or call is 'handy'.
What is your solution to those cross cutting concerns like logging?
Best regards
McA | [reply] [d/l] [select] |
|
What is your solution to those cross cutting concerns like logging?
What is logging? Simply stated, it is printing to a filehandle.
Pretty much everyone is comfortable using STDOUT and STDERR. And STDERR serves all my logging needs.
But if you want your logging to go to a different place than STDERR, what's wrong with (say) STDLOG?
Point it to a file or port as needed.
Want to turn logging off, direct it to the null device.
Want your logging to add boilerplate (timestamps, callstack, threadids etc.), tie *STDLOG.
Once it is tied, routing to multiple destinations is easy.
IMO, L::L4p is a "let's pretend we're java bunnies", grandiose overkill, behemoth of a package dynasty of packages, that makes writing a few bits of text to a file, laborious, complicated and expensive.
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".
| [reply] |
|
|
|
Re: Global or not global by Anonymous Monk on Jul 03, 2012 at 06:29 UTC |
Function a uses b and b has to use c. That means you have to insert dbhandle in the function signature of b even if b doesn't need it by itself.
I don't think it means that, I think it actually means dbhandle should be an attribute instead of an argument
| [reply] |
Re: Global or not global by moritz (Cardinal) on Jul 03, 2012 at 06:29 UTC |
(singleton = global variable)?
It is global state that is a problem, not just global variables. And yes, singletons are also global state. So you win nothing by using a singleton over a global variable.
So you have several options: you can understand why global state is bad, and still decide to use it. Or you can go the OO route where the database handle is available.
| [reply] |
|
| [reply] |
|
| [reply] |
Re: Global or not global by cavac (Chaplain) on Jul 03, 2012 at 11:22 UTC |
As anybody would agree with: global variables are bad.
You mean like STDERR, @ARGV, %SIG?
SCNR
Sorry for any bad spelling, broken formatting and missing code examples. During a slight disagreement with my bicycle (which i lost), i broke my left forearm near the elbow. I'm doing the best i can here...
| [reply] |
|
I waited for that. :-)
The interesting aspect of these variables is: They are just there. Everyone expects them to be there. Regularly they are part of the runtime environment everywhere. So IMO they could be interpreted as a service which is always accessible.
How is this different to a global variable which you introduce as a part of your own "runtime environment"?
Best regards
McA
| [reply] |
Re: Global or not global by sundialsvc4 (Monsignor) on Jul 03, 2012 at 15:19 UTC |
Historically, I have dealt with the problem of “global DB handles” and other such things simply by defining a package named Global. This package contains functions which produce the necessary values, if necessary doing so on-demand. For example, my $dbh = Global::DBHandle;. (If you need to use more than one database, simply have a separate function to automagically produce each handle.) You can replace this functionality with stuff to, say, use a DB handle cache, without affecting anything else in the program. And that is what I consider to be a win: there is a globally-available yet concretely documented way to obtain the necessary values and handles, and each is a function that returns it. If anything “has to happen,” here is a central and obvious place to put that. It is crystal-clear what is being done and why. This has for a long time been my standard practice.
| [reply] |