http://qs1969.pair.com?node_id=246357

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

I have a file that I use as a configuration file...

It looks similar to this:
$default_font_family = qq~Arial~; $default_font_color = qq~#000000~; $standout_text_color = qq~navy~; $default_font_size = 2;
Of course that is just an example.

My question is this.

I created a MySQL database, with this format:
id = autoincrement...
name = VARCHAR(100) ex: default_font_size
valu = VARCHAR(255) ex: 2
t = TIMESTAMP for last updated time.

Is there a way I can put the name as a variable that can be used in every page, since it's called in a "required" file, Not in the main script?

Would something like this work...
use CONSTANT $row->{name} => $row->{valu};

Or is there another way to do it, where Perl will use it through out the whole 'site'?

thx,
Richard

Replies are listed 'Best First'.
Re: Constant Variables
by dragonchild (Archbishop) on Mar 27, 2003 at 23:31 UTC
    Modules that have use constant in them is a good start. Using your database to store such things is another good place, maybe in a table called constants with two columns - name and value (kinda like a hash). use Exporter is another good place. Also, using a Singleton object is a good place. There's a hundred different ways.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

    Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

      I like this method...
      maybe in a table called constants with two columns - name and value (kinda like a hash).

      That is what I'm doing, but how do I make it where the column "name" is like a variable, for instance if record 1 was this:
      color1 red

      How could I get it to have $color1 contain the value?

      In other words, in case I did not make it clear...

      $string1 = qq!Hello, my favorite color is $color1!;
      How would I get using a database to do that, using Perl?
      I don't see how the Export would do that, or the other things you showed.

      thx,
      Richard
        It sounds as if you want to bind the variable $color1 to the value of a the corresponding column in the current row. Check out the bind_col and bind_columns methods of DBI.

        Update: As CPAN appears to be down, here is the basic syntax (grabbed from perldoc DBI);

        $rc = $sth->bind_col($column_number, \$var_to_bind); and $rc = $sth->bind_columns(@list_of_refs_to_vars_to_bind);
        The variables pretty much explain themselves ;-), but if you don't get it, do a perldoc DBI (or equivalent) and find the complete doc.

        I can't see how you can do well what you want; others more experienced may well have a trick to do it. Maybe something along the lines of:

        my $x = "variable_name"; my $value = "value"; eval "\$$x = $value"; warn $@ if $@; print $color1;

        Which works, but not under use strict.

        My suggestion would be to change your approach to use a hash. This would greatly simplify things.

        my %config; # use database (DBI) to read key / values into hash # ... $config{color1} = "red"; print $config{color1};

        Update: Just re-read your question. You want a way to provide access to the %config hash on each page. You could use a module to do this, exporting the %config hash.

        You don't want to do that. You want to have a hash of configuration values. That way, you do something like:
        my $string1 = qq!Hello, my favorite color is $config{color1}!;

        ------
        We are the carpenters and bricklayers of the Information Age.

        Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

        Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

Re: Constant Variables
by dga (Hermit) on Mar 28, 2003 at 16:44 UTC

    Storing preferences in the database might be done like so.

    create table prefs ( user_login text, color1 text, color2 text, fontsi +ze text, ... , primary key (user_login) );

    Later in Perl

    use constant DS => 'my dsn here'; # later ... my $dbh=DBI->connect(DS); my($color1, $color2, $fontsize); eval { my $sth=$dbh->prepare("SELECT color1, color2, fontsize, ... FROM pre +fs WHERE user_login=?"); $sth->execute($login); $sth->bind_columns( \( $color1, $color2, $fontsize ) ); $sth->fetch; $sth->finish; # using primary key to only fetch 1 row }; if($@) { print STDERR "Informative error message goes here with $@ for good m +easure\n"; }

    This will bind color1 to $color1 etc. They will be undef if they aren't set in the database. Another option is to have a prefs hash so that you dont have a zillion named variables all floating around for a long time all doing the same thing. But if you ant to add a new preference type you need to alter the prefs table and change the code everywhere prefs are accessed.

    #change lines from above my($color1 ...); #becomes my $prefs; #bind_columns becomes $sth->bind_columns( \my( $c1, $c2, $fs ) ); $prefs={ color1 => $c1, color2 => $c2, fontsize => $fs }; #later to get a pref print "My favorite color is $prefs->{color1}\n";

    The bind columns could be done other ways like binding directly into $prefs. This way makes the bind_columns short and makes the assignment to $prefs seperate so if it gets long it can be split over many lines for clarity. If you add a new preference this makes a new bind variable you have to add and also change the prefs assignment also which is a drawback. Another drawback is that a new preference type requires altering the prefs table in the database.

    My preferred way to set up the table would be.

    create table prefs ( user_login text, prefname text, prefvalue text, p +rimary key ( user_login, prefname) );

    Then prefs can be added as desired to the database and the perl code pick them up next time through.

    my %prefs; ... eval { my $sth=$dbh->prepare("SELECT prefname, prefvalue FROM prefs WHERE u +ser_login=?"; $sth->execute($login); $sth->bind_columns( \my( $n, $v ) ); while($sth->fetch) { $prefs{$n}=$v; } }; if($@) { #as before } #later to use print "My favorite color is $prefs{color1}\n"; # or even foreach my $p ( keys %prefs ) { print "I like my $p to be $prefs{$p}\n": }

    Now adding a pref to the database will make it available in %prefs to your CGI programs. Any unset prefs in the database are not loaded into the hash at all and defaults could be used etc. This version only loads prefs which are defined for the current user into your address space and a new preference only needs to be referenced in the perl code and users which want that preference get it in the database and it magically is available in all scripts which access the prefs table to use as they wish. This method is very extensible and the primary key assures that each user has exactly 0 or 1 preference of each type.