Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling

Retrieve value with key warns 'unitialized value' although present

by strawberrysocialist (Initiate)
on Dec 28, 2009 at 17:28 UTC ( #814634=perlquestion: print w/replies, xml ) Need Help??

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

First, I'm new to perl and am still working through Learning Perl 5th ed., in chapter 11. However, I've used both VBA and VB.Script a lot and some VB.Net so I'm not new to programming entirely.


I'm writing a simple backup program ( using rsync to a home server running ubuntu jaunty. I have a configuration file (backup.conf) that stores the details for rsync. I wrote my own code, sub load_config, to process the configuration file. (NOTE: I did this in lieu of using a CPAN module since I'm using cygwin on Win XP and could not get CPAN modules to install.) The sub processes the config file and uses the hash declared in the main procedure to store the keys and values.


Within the load_config sub I can retrieve the value for a key and print the entire hash out iteratively. Within the main procedure I can print the entire hash out iteratively but CAN NOT retrieve the value for a key. No matter how I try to use the key (no quotes, single or double quotes, assigning to a variable first) I'm warned about an 'unitialized value' and get nothing but an empty string.


I've tried googling and PerlMonks' super search but probably couldn't find the answer because of poor search terms. I found several tutorials and examples. Some of these use a bareword key within the braces, { }, others use double quotes, and a few use single quotes, providing I'm reading them correctly. I think it must be a syntax issue since I can iterate over the hash within the scope fo the main procedure, just not retireve the value using the key, both of which I can do within the subprocedure. I'm just puzzled and no doubt my lack of perl knowledge is hampering my ability to find the solution. I was tempted to throw my laptop around last night--way too tired and frustrated. I'd appreciate any help that points me in the right direction. The actual code and config data follow.


Script file --

This is an excerpt but contains all the code at issue

#!/usr/bin/perl #use 5.010; ############# I use this in the larger script , just not h +ere use strict; use warnings; my $debug = $ENV{"DEBUG"} // 1; # Debug set as default while te +sting my (%config, $key); &load_config ("./backup.conf"); # Location hardcoded for testing only while ( (my $key, my $value) = each %config ) { print "$key => $value\n"; } # Set parameters print "Setting parameters\n" if $debug; my @keys = ('RSYNC_OPTIONS', "RSYNC_OPTIONS"); #unshift @keys, RSYNC_OPTIONS; foreach (@keys) { $key = $_; print "$key\n"; # print "Exists\n" if exists $config{$key}; if (exists $config{$key}) { print "Exists\n"; print "Defined\n" if defined $config{$key}; print "True\n" if $config{$key}; print $config{$key} . "\n"; } else { print "$key does not exist\n"; } } print "No quotes:"; print $config{RSYNC_OPTIONS}; print "\nSingle quotes:"; print $config{'RSYNC_OPTIONS'}; print "\nDouble quotes:"; print $config{"RSYNC_OPTIONS"}; print "\n"; sub load_config { my $file = shift @_; print "Loading configuration file, $file\n" if $debug; my $opened = open CONFIG, "<", $file if (-e $file); if ($opened) { print "Opened configuration file, starting to process\n" if $d +ebug; while (<CONFIG>) { chomp; # Skip lines not containing a key-value pair s/#.*//; # no comments s/^\s+//; # no leading white s/\s+$//; # no trailing white next unless length; # anything left? # Split the line into the key and the value (my $key, my @value) = split /=/, $_; # my $temp = q/$key/; # print "$temp\n"; # $key = q/$temp/; my $value = join '=', @value; # $temp = q/$value/; # print "$temp\n"; # $value = q/$temp/; print "Retrieved key-value pair: $key => $value\n" if $deb +ug; $config{$key} = $value; print "$key holds $config{$key}\n" if $debug; } print "Finished processing, closing configuration file\n" if $ +debug; close CONFIG; } else { warn "Can not open the configuration file: $file (Reported err +or: $!)"; } $opened; }
Config file -- backup.conf
RSYNC_OPTIONS = -avvyz --delete RSYNC_RSH = ssh LOG-FILE = backup.log EXCLUDE-FROM = backup.exclude INCLUDE-FROM = backup.include

Replies are listed 'Best First'.
Re: Retrieve value with key warns 'unitialized value' although present
by bv (Friar) on Dec 28, 2009 at 17:50 UTC

    Whitespace! Your keys all have an extra space at the end, since you split on /=/. To fix, change your split to /\s*=\s*/. As a tip, when printing debug statements, use obvious delimiters to catch this kind of error. For example:

    while ( (my $key, my $value) = each %config ) { print "!$key! => ($value)\n"; }

    print map{substr'hark, suPerJacent other l',$_,1}(11,7,6,16,5,1,15,18..23,8..10,24,17,0,12,13,3,14,2,4);
Re: Retrieve value with key warns 'unitialized value' although present
by jethro (Monsignor) on Dec 28, 2009 at 17:54 UTC

    Just insert the following two lines after the call to load_config:

    use Data::Dumper; print Dumper(\%config);

    Data::Dumper ist in the core and should be available even without CPAN. Really one of the best tools for debugging (short of using the debugger itself)

    Since you probably don't want to wait for the surprise revelation, here is a spoiler:

Re: Retrieve value with key warns 'unitialized value' although present
by kennethk (Abbot) on Dec 28, 2009 at 18:41 UTC
    #use 5.010; ############# I use this in the larger script , just not here

    Actually, you do use it here. The // operator (C style Logical Defined Or) is new to 5.10.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://814634]
Approved by herveus
Front-paged by herveus
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (1)
As of 2022-01-29 05:20 GMT
Find Nodes?
    Voting Booth?
    In 2022, my preferred method to securely store passwords is:

    Results (74 votes). Check out past polls.