For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > December 2004 > return value for associate array









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author return value for associate array
Khairul Azmi

2004-12-17, 8:56 am

Hi,
I am working on a function that would simple store value assignments
statement into an array. The statement is stored in a text file. The
contains of the file would be

-----------
var word1 one,two,three
var word2 four,five,six
-----------

So I write a function that would read the file and return the variable
and the value in an associate array format. The value of the array at
the end should be

$conf['word1']="one,two,three";
$conf['word2']="four,five,six";

sub get_conf {
my $local_file = $_[0];
my @local_conf;

if (open (INFILE, "$local_file")) {
while (<INFILE> ) {
my $line = $_;

# if line is not a comment
if ($line !~ /^#|^\s/) {
my @conf_fields=split(/\s+/,$line);
if ( $conf_fields[0] eq "var" ) {
$local_conf[$conf_fields[1]] = $conf_fields[2];
}
}
}
close (INFILE);

print "A. $local_conf{'word1'} \n";
print "B. $local_conf{'word2'} \n";
return (@local_conf);
} else {
print "$0: file $local_file not found \n";
}
}

However the print statement at the very end of the function would only print
"A. four,five,six"
"B. four,five,six"

Where did I do wrong here? Thanks.
Tor Hildrum

2004-12-17, 8:56 am

On Fri, 17 Dec 2004 15:23:35 +0800, Khairul Azmi <khairul.azmi@gmail.com> wrote:

Hi, start your script with:
#!/usr/bin/perl -w
use strict;

> sub get_conf {
> my $local_file = $_[0];
> my @local_conf;


local_conf is an array. An assosiative array in Perl, is called a hash.
You declear it with:
my %hash;

> if (open (INFILE, "$local_file")) {
> while (<INFILE> ) {
> my $line = $_;
>
> # if line is not a comment
> if ($line !~ /^#|^\s/) {
> my @conf_fields=split(/\s+/,$line);
> if ( $conf_fields[0] eq "var" ) {
> $local_conf[$conf_fields[1]] = $conf_fields[2];


This is array subscription. What you really want is:
hash{key} = value

Basically:
my %hash;

get various $keys and $values in loop
then set $hash{$key} = $value;

> }
> }
> }
> close (INFILE);
>
> print "A. $local_conf{'word1'} \n";
> print "B. $local_conf{'word2'} \n";


You can't use an array like that, and you shouldn't use a hash like
that. Hardcoding the 'keys' you are getting dynamically is poor
design.

This is better, or you could use Data::Dumper
foreach (keys %hash) {
print "$_ -> $hash{$_}\n"
}

Tor
John W. Krahn

2004-12-17, 8:56 am

Khairul Azmi wrote:
> Hi,


Hello,

> I am working on a function that would simple store value assignments
> statement into an array. The statement is stored in a text file. The
> contains of the file would be
>
> -----------
> var word1 one,two,three
> var word2 four,five,six
> -----------
>
> So I write a function that would read the file and return the variable
> and the value in an associate array format. The value of the array at
> the end should be


What used to be called an "associate array" in Perl4 is now called a "hash" in
Perl5.


> $conf['word1']="one,two,three";
> $conf['word2']="four,five,six";
>
> sub get_conf {
> my $local_file = $_[0];
> my @local_conf;

^^^^^^^^^^^
You declare an "array" here not a "hash" (associate array).


> if (open (INFILE, "$local_file")) {
> while (<INFILE> ) {
> my $line = $_;
>
> # if line is not a comment
> if ($line !~ /^#|^\s/) {
> my @conf_fields=split(/\s+/,$line);
> if ( $conf_fields[0] eq "var" ) {
> $local_conf[$conf_fields[1]] = $conf_fields[2];

^^^^^^^^^^^^
You are storing data in the array @local_conf.


> }
> }
> }
> close (INFILE);
>
> print "A. $local_conf{'word1'} \n";

^^^^^^^^^^^^
> print "B. $local_conf{'word2'} \n";

^^^^^^^^^^^^
You are trying to print data from the hash %local_conf which apparently
doesn't exist.


> return (@local_conf);
> } else {
> print "$0: file $local_file not found \n";
> }
> }
>
> However the print statement at the very end of the function would only print
> "A. four,five,six"
> "B. four,five,six"
>
> Where did I do wrong here? Thanks.



You probably want something like this:

sub get_conf {
my $local_file = $_[0];
my %local_conf;
local *INFILE;

open INFILE, $local_file or do {
print "$0: file $local_file not found \n";
return;
}

while ( <INFILE> ) {
my ( $key, $data ) = /^\s+ var \s+ (\S+) \s+ (\S+)/x or next;
$local_conf{ $key } = $data;
}

print "A. $local_conf{'word1'} \n";
print "B. $local_conf{'word2'} \n";

return %local_conf;
}

__END__




John
--
use Perl;
program
fulfillment
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com