Reputation: 15
I'm working with an API to get Information and save it into a file
#!/bin/perl
use strict;
use warnings;
use JSON;
use Data::Dumper;
my %Hash;
my @Array;
my $url = "https://foo/bar"
my $apidata = `/usr/bin/curl -k -u $url`
my $apidatajson = decode_json $apidata;
my $i=0;
foreach(@{ $apidatajson->{category} }){
@Array=();
my $Name=$apidatajson->{category}[$i]{Name};
my $value=$apidatajson->{category}[$i]{Value};
push(@Array,($Name,$value));
$Hash{$Name}=@Array; # Output 1
$Hash{$Name}=\@Array; # Output 2
$i++;
}
print Dumper \%Hash;
Output 1 looks something like this:
$VAR1{
"FooName2" => 2;
"FooName" => 2;
};
Output 2 looks something like this:
$VAR1{
"FooName2" => [
"FooName2"
"FooValue2"
]
"FooName" => $VAR1 -> {'FooName2'}
};
Id need it to look like this:
$VAR1 {
"FooName2" => [
"FooName2"
"FooValue2"
]
"FooName" => [
"FooName"
"FooValue"
]
}
So essentially what I'm asking is, how can I save the content of the Array in the Hash, without using a Reference, so it doesn't mess up every entry but the last one?
Upvotes: 1
Views: 75
Reputation: 6626
The code in your question is not the code you are running. In particular, I suspect that you do not have the line my @Array = ()
but rather @Array = ()
(without my
).
Thus, $Hash{$Name} = \@Array;
takes the reference of the array declared outside of the foreach
loop (since there is actually none declared within the loop), which is why both values of your hashtable are the same.
If you declare @Array
within your loop, the your code works properly.
Additional notes:
Your seem confused between the "foreach" loop and the C-style for loop. Your loop should be:
for (@{ $apidatajson->{category}}){
my @Array;
my $Name = $_->{Name};
my $value = $_->{Value};
push(@Array,($Name,$value));
$Hash{$Name} = \@Array;
}
Or, since you don't really need @Array
, simply:
for (@{ $apidatajson->{category}}){
my $Name = $_->{Name};
my $value = $_->{Value};
$Hash{$Name} = [$Name, $value];
}
Or, if you need to keep your $i
:
for my $i (0 .. $#{$apidatajson->{category}}) {
my $Name = $apidatajson->{category}[$i]{Name};
my $value = $apidatajson->{category}[$i]{Value};
$Hash{$Name} = [$Name, $value];
}
You don't need to call curl
to do an http request. Instead, you can use a Perl module like LWP::Simple
:
use LWP::Simple;
my $apidata = get("https://foo/bar") or die "Failed to get data from API!";
Upvotes: 2
Reputation: 23764
Try this:
$Hash{$Name}=[$Name, $value];
Square brackets are array references in Perl.
You can not avoid an array reference, if you need it. Your requirements are contradictory.
BTW: what you have created in the second version is a cyclic reference. Probably because of the same variable name in the global and local scope. But I think the output does not belong to your code.
Upvotes: 1