http://www.perlmonks.org?node_id=512022


in reply to more fun w/ HASh ref's

G'day Hugh.

Might I suggest, for starters, that writing your own config parsing code is probably a mistake already? While I'm certain we can help you to get it working, you might find an existing module such as Config::IniHash, Config::Tiny or Config::General a better solution, especially in the long term. For your case I'd probably recommend Config::IniHash.

When is the error occuring? During compilation? During runtime? Can you compile the code as follows (outside of a CGI session)?

perl -cw yourcode.cgi

If it's happening during runtime, is it happening when you read in the config file, or when you later try to access it? If it's when you later try to access it, use Data::Dumper to have a look inside the config hash. Is it behaving as you'd expect?

# Generate config hash then... use Data::Dumper; print Dumper %config;

Try isolating the problem. Write a new program which reads in the config data and then accesses it as you want to. Try to make it as simple as possible, perhaps as below:

# Config_reader.pm package Config_reader; use base Exporter; use strict; use warnings; # etc while (<DB>) { chomp; next if /^\s*\#/; next if /^\s*$/; unless (/=/) { die "invalid variable assignment in supporters.db: $_"; } my ($key, $val) = split(/\s*=\s*/,$_,2); $key =~ s/^\s*//; $val =~ s/ *$//g; $config{db}{$key} = $val; $config{$key} = $val; } close DB; ## test.pl use Config_reader qw/%config/; use Data::Dumper \%config; my($host) = $config{db}{db_host_name}; my($db) = $config{db}{db_name }; my($user) = $config{db}{db_user }; my($pw) = $config{db}{db_pw };

If that doesn't work, then you've got something we can more easily help you debug. If it does work, then chances are that your problem is not actually where you think it is.

Either way, I strongly recommend you have a look at the already existing configuration modules.

All the very best,

jarich

Replies are listed 'Best First'.
Re^2: more fun w/ HASh ref's
by hesco (Deacon) on Dec 01, 2005 at 01:04 UTC
    Jarich:

    Thank you sir, for those leads.

    I've been running tests with Config::IniHash. Its working on every part of my barely edited config files, except for the heredoc variables in my supporters.copy.ini file.

    But now I'm getting this error:

    Wed Nov 30 16:41:47 2005 error client 24.67.197.93 Can't use an undefinedvalue as a HASH reference at /usr/lib/cgi-bin/bc/test.pl line 24.

    line 24 reads:

    my $options->{'heredoc'} = '1';
    I know someone here the other day was telling me I should not quote my hash keys, but on my installation it does not seem to work unless I do.

    #!/usr/bin/perl use strict; # use supporters_conf qw(%config); use Config::IniHash; # $hashreference = ReadINI ($filename, %options); use CGI; use CGI::Pretty qw(:all *table param); my $url = url(); # my $table1 = fqtn(@config{qw(db prefix)},"basetablename"); my $conf = parse_config_directory($url); my $path = $0; my $script = $0; $script =~ s/^(.*)\///; # $conf =~ s/$script//; # $path =~ s/$script/conf.d\/$conf\/supporters.conf/; my $config_conf = ReadINI ($conf); my $copy = $conf; $copy =~ s/\.conf/.copy/; my %options; my $options->{'heredoc'} = '1'; my $config_copy = ReadINI ($copy,%options); my $db = $conf; $db =~ s/\.conf/.db/; my $config_db = ReadINI ($db); print header("Testing parser for configuration files"), start_html("Testing parser for configuration files"), p("And the question of the hour is: Will the config module export t +he form copy. This experiment shall tell us."), p("Script path and name is: ".$0), p("Script name is: ".$script), # p("Scriptpath: ".$sp), # p("Scriptname: ".$sn), p("Path to configuration files at: <b>".$conf."</b>"), p("Script accessible at: ".$url), # p("Fully Qualified Table Name looks like: ".$table1), p("Config::IniHash says \$config = ".$config_conf."."), p("And the mail-abuse address is: ".$config_conf->{'mail-server'}->{ +'mail_abuse'}."."), p("The database name is: ".$config_db->{'db'}->{'db_name'}."."), p("The donor form disclaimer reads: <br>".$config_copy->{'copy'}->{' +donor_form_disclaimer_copy'}."."), p(),p(), $supporters_conf::config{'donor_thanks'}, end_html(); exit; sub parse_config_directory() { my($conf)=@_; # call as follows # use CGI; # $url = url(); # $conf = parse_config_directory($url); my $scriptpath = $0; my $scriptname = $0; $scriptname =~ s/^(.*)\///; $scriptpath =~ s/$scriptname//; $conf =~ s/https:\/\///; $conf =~ s/http:\/\///; $conf =~ s/\//./g; $conf =~ s/\.$scriptname//; $conf = $scriptpath."conf.d/".$conf."/supporters.conf.ini"; return $conf; # configuration file, ready for execution } # END parse_url sub fqtn(){ my($db,$prefix,$table)=@_; $db =~ s/ *$//; $prefix =~ s/ *$//; $table =~ s/ *$//; my $fullyqualifiedtablename = $db.".".$prefix.$table; return $fullyqualifiedtablename; } # END fqtn
    Any ideas how I might work through this one? I've written this multiple ways and keep getting one error or another.

    -- Hugh

      Consider the following code snippet:
      my %options; my $options->{'heredoc'} = '1'; my $config_copy = ReadINI ($copy,%options);

      What this is actually saying is annotated below.

      # Create a hash called %options my %options; # Create a *scalar* variable called $options and then try # to use it as a reference. Since it's just been created, # it's undefined. Hence this won't work. my $options->{'heredoc'} = '1'; # Call ReadINI passing it $copy and your %options hash. my $config_copy = ReadINI ($copy,%options);

      I imagine that the line you want to have in the middle there is:

      $options{heredoc} = 1;

      It's a hash look up. %options is a hash, not a hash reference. If its not a reference, you don't want the arrow.

      I hope this helps.

      jarich