Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Arrary ref stored in hash always points to the same array?

by Anonymous Monk
on Mar 01, 2002 at 17:37 UTC ( [id://148620]=perlquestion: print w/replies, xml ) Need Help??

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

I've got a file of space seperated names. When I run this code
while (<>) {

    chomp;

    @ary = split;

    $user = shift @ary;

    $cluster{$user} = \@ary;

    undef @ary;
}

foreach $user ( sort ( keys ( %cluster ))) {

    print "$user $cluster{$user} @{$cluster{$user}}\n";
}
I expect to see output like

username ARRAY(0x8101b94) username's_friend

but I don't get username's_friend at all, and the ARRAY pointer I get is always the same, and alway the array that points to the last line of input. -clay

  • Comment on Arrary ref stored in hash always points to the same array?

Replies are listed 'Best First'.
(Ovid) Re: Arrary ref stored in hash always points to the same array?
by Ovid (Cardinal) on Mar 01, 2002 at 17:47 UTC

    If you were using strict, you wouldn't probably wouldn't be having this problem because you would have declared @array with my and made it lexically scoped. As it is, you're using a global variable, thus always pointing to the same reference. However, even lexically scoping the array isn't going to help because you're calling undef on the array that you're pointing to. The following should work. I replaced your for loop with a call to Data::Dumper to make it easier to see the results.

    use strict; use Data::Dumper; my %cluster; while (<DATA>) { chomp; my @ary = split; my $user = shift @ary; $cluster{$user} = \@ary; } print Dumper \%cluster; __DATA__ bob's your uncle Ovid is in da house

    To get a little more specific, if you use a variable without declaring it (such as when you fail to use strict and my), the variable is automatically created as a global variable in the current namespace. For most programs, this means your variables with be in the main:: namespace. Your @ary is actually @main::ary. Every time you took a reference to it, it was the same array.

    When you lexically scope a variable by declaring it with my, you create a new, private instance of that variable that has absolutely no relation to a global variable of the same name. For instance, these two instances of $foo are not the same:

    #!/usr/bin/perl $foo = "bar"; { my $foo = "something else"; print "$foo\n"; } print "$foo\n";

    Behavior like this can introduce plenty of subtle bugs, if people are unaware of what's going on. By always using strict, you can avoid these bugs.

    Cheers,
    Ovid

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Re: Arrary ref stored in hash always points to the same array?
by VSarkiss (Monsignor) on Mar 01, 2002 at 17:47 UTC

    Think of this way: you're setting $cluster{$user} to a reference to the same array every time. Why would you expect a different value?

    A simple rewrite that does what you want is to use an anonymous array reference right up front:

    while (<>) { chomp; $ref = [ split ]; # new anon.array every iteration $user = shift @$ref; $cluster{$user} = $ref; }
    Some cleanup is possible (mainly using strict and tightening up the code a bit), but I wanted to make the line-by-line correspondence to your code clear.

    HTH

    Update
    Took out a confusing sentence....

•Re: Arrary ref stored in hash always points to the same array?
by merlyn (Sage) on Mar 01, 2002 at 23:48 UTC

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://148620]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (4)
As of 2024-04-25 16:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found