Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Variable Declaration

by ant (Scribe)
on Oct 19, 2001 at 14:44 UTC ( [id://119936]=perlquestion: print w/replies, xml ) Need Help??

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

Any advice is gratefully recieved.
My problem is that I have a small database, with about
15 scripts accessing the database using Perl DBI.

Should I declare the database, username and password as
variables private to that script using my $database = 'live' etc.
This would mean that any changes to the database would mean
me visiting each script and changing the code.

OR should I create a package and declare the variables there
and then export them into each script.
This would then mean they are global variables, but at least
I only have to visit one file to change the details.

OR should I create a functions file, that is used in the main
script with a sub routine called get_db_details (and declare
the variables there) that would then return the details of the
db into variables in the main script.
This again would mean that I would only have to access one
file to make changes.

Many Thanks
Ant

Replies are listed 'Best First'.
Re: Variable Declaration
by MZSanford (Curate) on Oct 19, 2001 at 14:56 UTC
    This is a question for the ages. I, personally, and i think most people will agree, Like to put such information in the module. This way, as you said, if it changes , you only change on portion. Also, since i don't like exporting things, i use function calls, like &DB_SERVER(), or some such maddness.

    A big advantage to using function calls, is that if you ever deside to hold the logins/passwords in some sort of encrypted form, you can change the functions and all of the code can go about it's merry way ... per the monk quips :

    Think about Loose Coupling
    i had a memory leak once, and it ruined my favorite shirt.
Re (tilly) 1: Variable Declaration
by tilly (Archbishop) on Oct 19, 2001 at 16:12 UTC
    I would write a module that gives back an open database handle to the scripts.

    Simple need. Simple interface. Don't keep on rewriting the connect code. Don't duplicate information.

      I agree fully. I adopted this solution whch lead to inteminable arguments with my colleagues which I grew weary of and relented. The problems that occured by moving the data into an exporting module were many, and I sorely regretted giving way.

      So to reiterate. Create a class that represents an open connection to the database. Simple, effective, and minimizes code waste.

      Yves
      --
      You are not ready to use symrefs unless you already know why they are bad. -- tadmc (CLPM)

        Well I cheated. I hid the data from the module that gave out the database handles into a config file, and I reexported that data to one other module.

        Turns out that some bulk database transfers were orders of magnitude faster with bcp, so I really did need the name/password. But only in one controlled situation...

Re: Variable Declaration
by blackmateria (Chaplain) on Oct 19, 2001 at 15:03 UTC
    Duplicated code and global variables are both pure evil, IMHO. I'm not sure which is worse in general, but in this case I think having the same info duplicated between 15 scripts would definitely be more of a Bad Thing(tm) than using globals (/me dons handy flame-retardant suit... :)

    I think the best choice you mentioned is definitely the "functions file" method (a module even?) with a function returning the proper settings. Personally, I wouldn't hard-code global values into the code though, at least not if they're likely to ever change. Use a separate configuration file (e.g. a text file) instead. This way once you get your code working you don't have to go back and change it just because you moved the database.

    Hope this helps!

Re: Variable Declaration
by andreychek (Parson) on Oct 19, 2001 at 17:30 UTC
    Of the many ways you could go about doing this, one possible method is to write a configuration file for your program.

    The mod_perl guide has a section on writing configuration files. While it is part of the mod_perl guide, by no means do you need to be using mod_perl to make use of it.

    They take you from the quick, "false lazy" method of writing them, to a very nice, flexible system. As a spoiler, this is the style config file they end up leading you to. The code I'm pasting here is directly out of the mod_perl guide, I did not write it myself, although I did add a few comments:
    # Config Module package My::Config; use strict; use vars qw(%c); # Create a hash containing our config data %c = ( dir => { cgi => "/home/httpd/perl", docs => "/home/httpd/docs", img => "/home/httpd/docs/images", }, url => { cgi => "/perl", docs => "/", img => "/images", }, color => { hint => "#777777", warn => "#990066", normal => "#000000", }, ); # Main program code (in a seperate file of course) use strict; use My::Config (); use vars qw(%c); *c = \%My::Config::c; print "Content-type: text/plain\r\n\r\n"; print "My url docs root: $c{url}{docs}\n";
    Again, this code is directly from the mod_perl guide. So what they are offering here is basically a big hash, which is made global. And whatever modules you are creating are capable of making use of that existing hash, by referencing the full package variable name. They just make an alias to that package variable by doing "*c = \%My::Config::c". And anywhere in your program, you can access the data in that config file by just saying "$c{url}{docs}" and the like.

    Have fun!
    -Eric
      Wouldn't it be just as simple to have the configuration module return a hash reference via a function? That way, the program is somewhat easier to read:
      use strict; use My::Config 'GetConfig'; my $config = GetConfig(); print "Content-type: text/plain\r\n\r\n"; print "My url docs root: $config->{url}{docs}\n";

      buckaduck

Re: Variable Declaration
by tstock (Curate) on Oct 19, 2001 at 16:52 UTC
    Either way (pakage or function file) sounds good, but I would make a configuration file. There are several modules to help ou with that on CPAN.

    In addition to database information, I place paths, filenames, debug levels and anything else that is static in there.

    You could also declare a bunch of constants in a file to be required.

    Tiago

      My god. NO!!! It's the dreaded "me too" post!

      I like a combination of these ideas.

      Maintain a module that will give you the open handle, that uses a config file to grab it. That way you can play all the games you want with specifying config files and datasources hot.

      We have a bunch of code that we all of a sudden needed to link to multiple databases (*sniff* *sniff* legacy system? Yep, the tracks are still warm.) And that approach saved our collective posteriors.


      $.02

      - V
Re: Variable Declaration
by buckaduck (Chaplain) on Oct 19, 2001 at 18:17 UTC
    Not only does the use of a configuration file make the scripts more maintainable, it can be used to increase security.

    If you're accessing a database and don't want to prompt for a username and password every time, you can keep the username and password information in the configuration file.

    Be sure to set the permissions of the configuration file so that it is only readable by a certain group (It's probably best to have a new group created for this purpose only). Set the group ownership of your scripts to this group id, and make the scripts run setgid (chmod g+s filename). You can set this up easily if you have administrative priveleges on your computer.

    buckaduck

Re: Variable Declaration
by zakzebrowski (Curate) on Oct 19, 2001 at 18:31 UTC
    Erg, if you are already using dbd, why not install dbi::csv? That would allow you to select all configuration variables using standard sql from a file that everyone can access?

    ----
    Zak
Re: Variable Declaration
by sheridan3003 (Beadle) on Oct 19, 2001 at 21:52 UTC

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://119936]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (4)
As of 2024-04-25 16:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found