CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Intermediate:
Is this an array of hashes?

 



kencl
User

Aug 26, 2001, 9:28 AM

Post #1 of 12 (1001 views)
Is this an array of hashes? Can't Post

Hi Folks,

I need to construct a data structure which looks like this:

Code
$DataStructureRef = [ "field" => "value1", 
"field" => "value2",
"ad" => "nauseum"
];

Can I do it like this (the order in the datastructure is not important)?

Code
$hash1{'field'} = 'value1'; 
$ad = "ad"; $nauseum = "nauseum";
%hash2 = ('field' => 'value2', $ad => $nauseum);
$array[0] = \%hash1;
push(@array, \%hash2);
$DataStructureRef = \@array;

Thanks for the help :)

>> If you can't control it, improve it, correlate it or disseminate it with PERL, it doesn't exist!


mhx
Enthusiast / Moderator

Aug 26, 2001, 9:52 AM

Post #2 of 12 (1001 views)
Re: Is this an array of hashes? [In reply to] Can't Post

Just do it like this:

Code
$DataStructureRef = { 
field => [
"value1",
"value2",
],
ad => [
"nauseum",
],
};

Which is actually a hash of arrays, but I think it matches your problem.
Hope this helps.

-- Marcus


Code
s$$ab21b8d15c3d97bd6317286d$;$"=547269736;split'i',join$,,map{chr(($*+= 
($">>=1)&1?-hex:hex)+0140)}/./g;$"=chr$";s;.;\u$&;for@_[0,2];print"@_,"



kencl
User

Aug 26, 2001, 10:08 AM

Post #3 of 12 (999 views)
Re: Is this an array of hashes? [In reply to] Can't Post

If I do it that way though, $DataStructureRef is a hash reference, not an array reference.

The confusing part for me is the contents of the anonomous array. I know arrays hold strings or references, but what is this trying to hold? In my way of thinking, if it was an array of hash references it would have to be created like this:

Code
$DataStructureRef = [ { "field" => "value1"}, {"field" => "value2"}, {"ad" => "nauseum"}]

Maybe a better way to ask the question is what does $DataStructureRef[1] contain (when created properly like at the top of my first post)? Is it:

$hashref = $$DataStructureRef[1] # $hashref can now be dereferenced with $$hashref{'field'}, which contains the string "value2" or
$string = $$DataStructureRef[1] # $string contains the string "field => value2"

I know it can't contain a hash because you can't do $array[5] = %anyhash

Thanks for the help.

>> If you can't control it, improve it, correlate it or disseminate it with PERL, it doesn't exist!


mhx
Enthusiast / Moderator

Aug 26, 2001, 10:54 AM

Post #4 of 12 (997 views)
Re: Is this an array of hashes? [In reply to] Can't Post


In Reply To
If I do it that way though, $DataStructureRef is a hash reference, not an array reference.

Right. Smile

In Reply To
The confusing part for me is the contents of the anonomous array. I know arrays hold strings or references, but what is this trying to hold? In my way of thinking, if it was an array of hash references it would have to be created like this:

Code
$DataStructureRef = [ 
{ "field" => "value1"},
{"field" => "value2"},
{"ad" => "nauseum"}
]


If you really wanted to build an array of hashes, this would be the right way. Now, arrays always hold so-called SVs, scalar values. A scalar value can be a string, a numeric value, a reference (and if I recall this right from the perlguts manpage even some other things).
If the content of an SV is a reference to an array, hash or subroutine, you can use the pointer (->) syntax borrowed from C to actually access the referenced object. Say you have

Code
my $stuff = [1, 2, 3];

Then $stuff is a SV that holds a reference to an array. You could access the array's elements using:

Code
$$stuff[0] 
$$stuff[1]
$$stuff[2]

or, which I find more readable:

Code
$stuff->[0] 
$stuff->[1]
$stuff->[2]

Maybe it's because I originate from C programming that I find this more readable, but to me it expresses more explicitly that $stuff is a reference. If you have something more complex, like a reference to an array that holds references to a subroutine, another array and a hash:

Code
my $stuff = [ 
sub { print 'subroutine' },
[1, 2, 3, 4, 5],
{key => 'value'},
];

Then you can call the subroutine by writing

Code
$stuff->[0]->();

access the array by writing

Code
$stuff->[1]->[2];

and access the hash table with

Code
$stuff->[2]->{key};

And, there's also a shortcut so you don't have to type too many ->'s if your structures get too deeply nested:

Code
$stuff->[0](); 
$stuff->[1][2];
$stuff->[1]{key};

I hope this will make the whole thing a bit clearer.

-- Marcus

P.S.: Yes, seems there's not so many people around at the moment. Wink


Code
s$$ab21b8d15c3d97bd6317286d$;$"=547269736;split'i',join$,,map{chr(($*+= 
($">>=1)&1?-hex:hex)+0140)}/./g;$"=chr$";s;.;\u$&;for@_[0,2];print"@_,"



kencl
User

Aug 26, 2001, 11:42 AM

Post #5 of 12 (995 views)
Re: Is this an array of hashes? [In reply to] Can't Post

Thanks for all the help mxh. I sure love perl, but sometimes sheesh... :)

Really my basic question is if I construct @FormData as below, what are the contents of say $FormData[1]? Is it a hash reference?

To give my post some context, here's what I'm trying to do:

Code
$PostID = '5';  # because this is actually part of a bigger operation 
# begin constructing form data array
@FormData = ('field1' => 'value1', 'field2' => 'value2'); # never tried this, hope it works :)
# do a bunch of stuff then add more form data
push(@FormData, 'field3' => 'value3', 'field3' => 'value4'); # select box with multiple selections allowed
# post form
$resulthashref = &PostForm('http://anywhere.com/receiveform.cgi', \@FormData);
unless ($resulthashref ->{'thispostrequestsucceededbrilliantly'}) {
&LogFailure("POST operation $PostID failed with statuscode: ".$resulthashref -> {'statuscode'}." and message: ".$resulthashref -> {'msg'});
# handle failure nicely, and yes there's a reason I'm logging the failure AFTER the returning from the subroutine,
# but I've stripped the code in the interest of brevity.
}

sub PostForm {
my ($PostURL, $FormDataPointer) = @_;
$postengine = LWP::UserAgent->new();
$req = POST $PostURL, $FormDataPointer;
$responsepage = $postengine->request($req) || &LogFailure("Unable to perform POST operation in sub PostForm");
unless ($responsepage -> is_success()) { # response code is NOT in the 200 range
$thiscode = $responsepage -> code(); $thismsg = $responsepage -> message();
return { 'thispostrequestsucceededbrilliantly' => 0, 'statuscode' => $thiscode, 'msg' => $thismsg };
}
return {'thispostrequestsucceededbrilliantly' => 1};
}

PS sorry for the horizontal scrolling; I like long, tight code lines :)

>> If you can't control it, improve it, correlate it or disseminate it with PERL, it doesn't exist!


mhx
Enthusiast / Moderator

Aug 26, 2001, 12:07 PM

Post #6 of 12 (994 views)
Re: Is this an array of hashes? [In reply to] Can't Post


In Reply To
Thanks for all the help mxh. I sure love perl, but sometimes sheesh... :)

mhx, but I won't care too much... Wink And it's always good to love Perl.

In Reply To
Really my basic question is if I construct @FormData as below, what are the contents of say $FormData[1]? Is it a hash reference?

No. It's just "value1". I hope you don't start to dislike Perl now ;-) Mainly, the => is nothing but a comma. Its only special behaviour is that it automatically quotes the string on the left of it. So

Code
(test => 'value', hello => 5)

is exactly the same as

Code
('test', 'value', 'hello', 5)

Well, nothing more to say ;-)
In the context of your script, the usage seems to be completely ok to me. The POST function from the HTTP::Request::Common module takes either a hash or an array reference as its argument, so it doesn't seem too wrong to pass a reference to an array.

-- Marcus


Code
s$$ab21b8d15c3d97bd6317286d$;$"=547269736;split'i',join$,,map{chr(($*+= 
($">>=1)&1?-hex:hex)+0140)}/./g;$"=chr$";s;.;\u$&;for@_[0,2];print"@_,"



kencl
User

Aug 26, 2001, 12:24 PM

Post #7 of 12 (994 views)
Re: Is this an array of hashes? [In reply to] Can't Post

Blush DOH! sorry about your alias.

That's it? It's as simple as that? Oh man, that's easy.Laugh I can just:

Code
push(@FormData, $fieldname);   push(@FormData, $value);

I'll always love perl because, like today with your help, I've learned a few good datastructure constructions.Cool

>> If you can't control it, improve it, correlate it or disseminate it with PERL, it doesn't exist!


mhx
Enthusiast / Moderator

Aug 26, 2001, 12:32 PM

Post #8 of 12 (993 views)
Re: Is this an array of hashes? [In reply to] Can't Post


In Reply To
That's it? It's as simple as that? Oh man, that's easy. I can just:

Code
push(@FormData, $fieldname);   push(@FormData, $value);


Yes. And, if you like, you could even do

Code
push @FormData, $fieldname => $value;

which adds some more coolness to the push. Cool

-- Marcus


Code
s$$ab21b8d15c3d97bd6317286d$;$"=547269736;split'i',join$,,map{chr(($*+= 
($">>=1)&1?-hex:hex)+0140)}/./g;$"=chr$";s;.;\u$&;for@_[0,2];print"@_,"



kencl
User

Aug 26, 2001, 12:45 PM

Post #9 of 12 (992 views)
Re: Is this an array of hashes? [In reply to] Can't Post

Actually your last suggestion is a good idea because I have the data in a hash anyway, so I can just write:

Code
foreach $key (keys %Hash) { 
push(@FormData, $key => $DataHash{$key});
}

Keeps things nice and neat.
Cool Cool == very cool!

>> If you can't control it, improve it, correlate it or disseminate it with PERL, it doesn't exist!


mhx
Enthusiast / Moderator

Aug 26, 2001, 12:50 PM

Post #10 of 12 (991 views)
Re: Is this an array of hashes? [In reply to] Can't Post

Then, what about the even cooler (CoolCoolCool)

Code
push @FormData, %hash;

One basic rule in the design of Perl was that it has to DWIM. (Do What I Mean.) In most cases, Perl simply does what you mean, and this makes it a super-cool language!

-- Marcus


Code
s$$ab21b8d15c3d97bd6317286d$;$"=547269736;split'i',join$,,map{chr(($*+= 
($">>=1)&1?-hex:hex)+0140)}/./g;$"=chr$";s;.;\u$&;for@_[0,2];print"@_,"



mhx
Enthusiast / Moderator

Aug 26, 2001, 12:52 PM

Post #11 of 12 (991 views)
Re: Is this an array of hashes? [In reply to] Can't Post

Or why don't you directly pass a reference to your hash to POST?

-- Marcus

Hey, Cool this was my 300th post!


Code
s$$ab21b8d15c3d97bd6317286d$;$"=547269736;split'i',join$,,map{chr(($*+= 
($">>=1)&1?-hex:hex)+0140)}/./g;$"=chr$";s;.;\u$&;for@_[0,2];print"@_,"



(This post was edited by mhx on Aug 26, 2001, 11:53 AM)


kencl
User

Aug 26, 2001, 1:32 PM

Post #12 of 12 (990 views)
Re: Is this an array of hashes? [In reply to] Can't Post

That is tre-cool CoolCoolCool

I don't pass a reference directly for two reasons:
1) I need to build up the data fields at various points during the script; sometimes they are in a hash, sometimes not.
2) hashes can't hold two separate values for a single key, as you see when preparing to send a select box with multiple values
I don't think you can do:
%hash = ('key' => 'value1', 'key' => 'value2'); # same key name
If I did, I think I'd either get a syntax error or value2 would overwrite value1.

>> If you can't control it, improve it, correlate it or disseminate it with PERL, it doesn't exist!

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives