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

Hi, this is closely related to another question I asked here recently, but I'm still struggling to really grok this stuff. :-) I have a list of hashrefs that I can work with very nicely a la:
foreach my $response ( @ $address ) { print "name: $response->{Addressee}<br>"; print "street: $response->{Street}<br>"; ...etc.
But sometimes I get just a single hash ref with the same data, and what I'd like to know how to do is force it into a list so that I can use the above loop to process it as a single element list. Sounds easy, right? But I'm getting no where with for example:
if ( ref $address eq HASH ) { my $templist = [ $address ]; }
or
if ( ref $address eq HASH ) { push my @templist, $address; }
Which seems logical to me, but when I print or ref the new variable I get nothing, when I'm expecting "ARRAYx...". Clearly I'm misunderstanding something here..and I'd be grateful for any feedback!

p.s. this is data generated from XML::Simple, and I could use the ForceArray option there, but I just *kinda really want to know how to do it because it's driven me crazy for an hour now* :-)

Replies are listed 'Best First'.
Re: Pushing a hashref into an array
by gmargo (Hermit) on Nov 08, 2009 at 10:20 UTC

    Perhaps try printing the confusing parts with Data::Dumper?

Re: Pushing a hashref into an array
by 7stud (Deacon) on Nov 08, 2009 at 13:01 UTC

    Maybe this is it:

     ref EXPR
     ref          Returns a non‐empty string if EXPR is a reference

    You wrote this:

    if ( ref $address eq HASH )

    HASH doesn't look like a string to me. Here is a proof of concept:

    use strict; use warnings; use 5.010; my %h1 = qw{Addressee David Street Street1}; my %h2 = qw{Addressee Kathy Street Street2}; my $templist; #my $address = [\%h1, \%h2]; my $address = \%h1; if (ref $address eq 'HASH') { $templist = [$address]; }else{ $templist = $address; } foreach my $response ( @ $templist ) { print "name: $response->{Addressee}<br>\n"; print "street: $response->{Street}<br>\n"; } --output:-- name: David<br> street: Street1<br>
    You can toggle the comment to see that the code works for a reference to an array of hashes, as well as a reference to a hash.
Re: Pushing a hashref into an array
by Anonymous Monk on Nov 08, 2009 at 10:09 UTC
Re: Pushing a hashref into an array
by Bloodnok (Vicar) on Nov 08, 2009 at 17:53 UTC
    Do you mean something along the lines of: foreach my $response ( @{ ref $address eq 'HASH' ? [ $address ] : $address } ) {... e.g.
    use warnings; use strict; #use autodie; use Data::Dumper; my $hr = { qw/hk1 hv1 hk2 hv2/ }; my $ar = [ { qw/ak11 av11 ak12 av12/ }, { qw/ak21 av21 ak22 av22/ } ]; foreach (@$ar) { warn Dumper $_ } foreach (@{ ref $hr eq q/HASH/ ? [ $hr ] : $hr }) { warn Dumper $_ }
    $ perl tst.pl $VAR1 = { 'ak12' => 'av12', 'ak11' => 'av11' }; $VAR1 = { 'ak22' => 'av22', 'ak21' => 'av21' }; $VAR1 = { 'hk2' => 'hv2', 'hk1' => 'hv1' };
    A user level that continues to overstate my experience :-))
      Thanks All, anon was right--it was a dumb scoping problem. And I'm red faced about the lack of quotes around HASH--I promise not to post questions again when I'm sleepy. Bloodnok: this is very cool:
      foreach (@{ ref $hr eq q/HASH/ ? [ $hr ] : $hr })
      I'd been wracking my brains for a way to do that as well :-)