Re: Perl arrays and hashes

  • From: "Octavian Rasnita" <orasnita@xxxxxxxxx>
  • To: <programmingblind@xxxxxxxxxxxxx>
  • Date: Tue, 14 Oct 2008 20:36:28 +0300

If you write only
@macs{$key}
perl understands that this is an array of the values for the keys found between { and }. Now it happends that the array of those keys contains only a single element ($key) but it could contain more like in this example:

use strict;

my %macs = (
key1 => 'test',
key2 => [1, 2, 3],
);

The following line should print the values for all the keys specified between { and }:

print @macs{('key1', 'key2')};

It prints:
testARRAY(0x28acdc)

The first value "test" is printed clearly because it is a scalar value. The second value is an array reference so it prints ARRAY(0x28acdc), but this just shows that all the values for the specified keys are printed.

So,
@macs{$key}
prints all the values that correspond to all the keys between { and }, which in this case is just one - $key.

Octavian

----- Original Message ----- From: "Sina Bahram" <sbahram@xxxxxxxxx>
To: <programmingblind@xxxxxxxxxxxxx>
Sent: Tuesday, October 14, 2008 5:04 PM
Subject: RE: Perl arrays and hashes


And that was the limitation of hashes I was not aware of. It actually makes
a certain degree of sense from a language internals point of view, but I
think that if Perl is so gunho  about hiding those details from the
programmer, it might have been nice for it to have supported that syntax I
typed up.

Thanks all, especially Teddy for offering the initial fix within a very
short period of time.

Take care,
Sina


-----Original Message-----
From: programmingblind-bounce@xxxxxxxxxxxxx
[mailto:programmingblind-bounce@xxxxxxxxxxxxx] On Behalf Of Jim Dunleavy
Sent: Tuesday, October 14, 2008 9:14 AM
To: programmingblind@xxxxxxxxxxxxx
Subject: Re: Perl arrays and hashes

Hi Sina,

You need to do @{$macs{$key}}.
A hash or array element can only contain a scalar (string, integer, float or
undefined), or a reference to an aggregate or other scalar.
When you initialize the key position with [], you're making your intention
explicit, an empty array is created and its reference is stored in the
hash table.
Otherwise the array is not created until you assign a value to its
first element.

HTH

--Jim

----- Original Message -----
From: Sina Bahram <sbahram@xxxxxxxxx>
To: <programmingblind@xxxxxxxxxxxxx>
Sent: Tuesday, October 14, 2008 1:50 PM
Subject: RE: Perl arrays and hashes


This is starting to get at what I was trying to say. If I set it equal to
[], then I won't need to do the @{$macs{$key}} but rather could do
@macs{$key}?

Take care,
Sina


-----Original Message-----
From: programmingblind-bounce@xxxxxxxxxxxxx
[mailto:programmingblind-bounce@xxxxxxxxxxxxx] On Behalf Of Jim Dunleavy
Sent: Tuesday, October 14, 2008 4:43 AM
To: programmingblind@xxxxxxxxxxxxx
Subject: Re: Perl arrays and hashes

Hi Sina,

@macs{$key} = ();
has the effect of assigning undefined to that key position.
It's the same as writing:
$macs{$key} = ();
If you have "use strict" perl will warn you of that usage.
When you write:
$macs{$key}[$i++] = $mac;
Perl replaces the previously assigned undefined scalar value with a newly
created array reference, making the previous assignment redundant.
To create an empty array reference for the mac address use:
$macs{$key} = [];

HTH

--Jim

----- Original Message -----
From: Sina Bahram <sbahram@xxxxxxxxx>
To: <programmingblind@xxxxxxxxxxxxx>
Sent: Tuesday, October 14, 2008 7:00 AM
Subject: RE: Perl arrays and hashes


> I did understand all of that, but I suppose I was asking about why perl
was
> treating it as a reference rather than doing the conversion itself.
> Regardless though, it all works and thanks.
>
> Take care,
> Sina
>
> -----Original Message-----
> From: programmingblind-bounce@xxxxxxxxxxxxx
> [mailto:programmingblind-bounce@xxxxxxxxxxxxx] On Behalf Of Octavian
Rasnita
> Sent: Tuesday, October 14, 2008 1:35 AM
> To: programmingblind@xxxxxxxxxxxxx
> Subject: Re: Perl arrays and hashes
>
> Hi,
>
> You need to write
>
> @{$macs{$key}}
>
> and not
>
> @macs{$key}
>
> because %macs is a hash and not an array to be noted with @ at the
> beginning.
>
> The %macs hash has a key named $key which happends to have an array as > a
> value.
>
> So you first need to specify that you want to address the key $key of
this
> hash, using
>
> $macs{$key}
>
> and derefference it to get its value... the array, using @{$macs{$key}}
>
> It is just like when you use
>
> my $hash_key = $macs{$key};
> my @array = @$macs_key;
>
> Of course, you need to add more braces like when you use
> my @array = @{$hash_key};
> because $macs{$key} already contains braces and you need to specify > that
the
> entire $macs{$key} is an array reference, not only $hash.
>
> Octavian
>
> ----- Original Message -----
> From: "Sina Bahram" <sbahram@xxxxxxxxx>
> To: <programmingblind@xxxxxxxxxxxxx>
> Sent: Monday, October 13, 2008 11:38 PM
> Subject: RE: Perl arrays and hashes
>
>
> > I'm off to try this out, but can you please explain why that is?
> >
> > I do understand why you're doing what you're doing, but I'm unclear > > as
to
> > why perl isn't doing this automatically?
> >
> > Take care,
> > Sina
> >
> >
> > -----Original Message-----
> > From: programmingblind-bounce@xxxxxxxxxxxxx
> > [mailto:programmingblind-bounce@xxxxxxxxxxxxx] On Behalf Of Octavian
> Rasnita
> > Sent: Monday, October 13, 2008 4:24 PM
> > To: programmingblind@xxxxxxxxxxxxx
> > Subject: Re: Perl arrays and hashes
> >
> > Hi,
> >
> > You need to use:
> >
> > for my $key (sort(keys(%macs)))
> > {
> > print "$key\n";
> > for my $val (@{$macs{$key}})
> > {
> > print "$val\n";
> > }
> > print "\n";
> > }
> >
> > Octavian
> >
> > ----- Original Message -----
> > From: "Sina Bahram" <sbahram@xxxxxxxxx>
> > To: <programmingblind@xxxxxxxxxxxxx>
> > Sent: Monday, October 13, 2008 10:50 PM
> > Subject: Perl arrays and hashes
> >
> >
> >> Hi all,
> >>
> >> I have a very simple program that loops through a file, whose
structure
> is
> >> like this.
> >>
> >> Key name:
> >> Value1
> >> Value2
> >> Value3
> >> ...
> >>
> >> Key name:
> >> Value1
> >> Value2
> >> .....
> >>
> >> Key name:
> >> Value1
> >> Value2
> >> Value3
> >> Value4
> >> ...
> >>
> >> And so on
> >>
> >> Not hard, right?
> >>
> >> I use the following snippet of code to parse that file.
> >>
> >> ***
> >>
> >> open(MACS, "macs.txt");
> >>
> >> my @macsFromFile = <MACS>;
> >> chomp @macsFromFile;
> >>
> >> my %macs;
> >> my $i = 0;
> >> for my $mac (@macsFromFile)
> >> {
> >> if($mac =~ /10.110.0.*/)
> >> {
> >> $key = $mac;
> >> $i = 0;
> >> @macs{$key} = ();
> >> }
> >>
> >> $macs{$key}[$i++] = $mac if($mac =~ /05:.*/);
> >> }
> >>
> >> ***
> >>
> >> Anyways, as far as I can tell, that works fine. When I print out the
keys
>
> >> of
> >> that hash, I get all the ip addresses I was looking for, but heaven
> forbid
> >
> >> I
> >> try to get the values. That's an insane nightmare.
> >>
> >> How can I loop through that hash, with each key, looping through > >> each
of
> >> the
> >> arrays stored at each key's index. After all, each key is an IP
address,
> >> and
> >> each IP address has a series of mac addresses associated with it in
this
> >> file, in the form of them being in an array assigned to that key in
the
> >> hash.
> >>
> >> So I wanted to make sure I parsed the file write. Thus, why not just
> print
> >> it out again and compare against the original. I tried the > >> following.
> >>
> >> ***
> >>
> >> for my $key (sort(keys(%macs)))
> >> {
> >> print "$key\n";
> >> for my $val (@macs{$key})
> >> {
> >> print "$val\n";
> >> }
> >> print "\n";
> >> }
> >>
> >> ***
> >>
> >> It prints out a single memory address rather than the list of the
> contents
> >> of that array.
> >>
> >> Why does it do this?
> >>
> >> I am using a for each construct to itterate through an array, and I
use
> >> the
> >> @ to indicate that I want array context to be used when I parse
> >> @macs{$key}
> >> ... What the heck else should I do to make perl understand I want to
loop
> >> through the array stored at @macs{$key}?
> >>
> >> Maybe I'm not doing this right up top? That's what I think the
problem
> is.
> >> Somehow I've given my hash a reference to an array, rather than the
array
> >> itself.
> >>
> >> Help!
> >>
> >> Take care,
> >> Sina
> >>
> >> __________
> >> View the list's information and change your settings at
> >> //www.freelists.org/list/programmingblind
> >>
> >
> > __________
> > View the list's information and change your settings at
> > //www.freelists.org/list/programmingblind
> >
> > __________
> > View the list's information and change your settings at
> > //www.freelists.org/list/programmingblind
> >
> __________
> View the list's information and change your settings at
> //www.freelists.org/list/programmingblind
>
> __________
> View the list's information and change your settings at
> //www.freelists.org/list/programmingblind
>

--------------------------------------------------------------------------
--
"Information in this email (including attachments) is confidential.
It is intended for receipt and consideration only by the intended
recipient.
If you are not an addressee or intended recipient, any use, dissemination,
distribution, disclosure, publication or copying of information contained
in
this email is strictly prohibited.  Opinions expressed in this email may
be
personal to the author and are not necessarily the opinions of the HSE.

If this email has been received by you in error we would be grateful if
you
could immediately notify the ICT Service Desk by telephone at +353 1
6352757

or by email to service.desk@xxxxxxxxxxxx and thereafter delete this
e-mail from your system"
--------------------------------------------------------------------------
--
__________
View the list's information and change your settings at
//www.freelists.org/list/programmingblind

__________
View the list's information and change your settings at
//www.freelists.org/list/programmingblind


----------------------------------------------------------------------------
"Information in this email (including attachments) is confidential.
It is intended for receipt and consideration only by the intended recipient.
If you are not an addressee or intended recipient, any use, dissemination,
distribution, disclosure, publication or copying of information contained in this email is strictly prohibited. Opinions expressed in this email may be
personal to the author and are not necessarily the opinions of the HSE.

If this email has been received by you in error we would be grateful if you could immediately notify the ICT Service Desk by telephone at +353 1 6352757

or by email to service.desk@xxxxxxxxxxxx and thereafter delete this
e-mail from your system"
----------------------------------------------------------------------------
__________
View the list's information and change your settings at
//www.freelists.org/list/programmingblind

__________
View the list's information and change your settings at
//www.freelists.org/list/programmingblind


__________
View the list's information and change your settings at //www.freelists.org/list/programmingblind

Other related posts: