FAQ
Hi All,

I am working on the below code to traverse through a hash, but it throws an error which states "Can't coerce array into hash at temp.pl line 6."

Code:
===============================================================
sub hash_walk {
my $self = shift;

my ($hash, $key_list, $callback) = @_;

while (my ($k, $v) = each (%$hash)) {
push @$key_list, $k;

if (ref($v) eq 'HASH') {
$self->hash_walk($v, $key_list, $callback);

}
else {
$callback->($k, \$v, $key_list);

} pop @$key_list;

$hash->{$k} = $v;
}
}
my %data = (
a => {
ab => 1,
ac => 2,
ad => {
ada => 3,
adb => 4,
adc => {
adca => 5,
adcb => 6,
},
},
},
b => 7,
c => {
ca => 8,
cb => {
cba => 9,
cbb => 10,
},
},
);
hash_walk(\%data, [], \&replace_all_val_strings);
sub replace_all_val_strings {
my ($k, $v, $key_list) = @_;
printf "k = %-8s v = %-4s key_list = [%s]\n", $k, $$v, "@$key_list";
$$v =~ s/oldstr/newstr/;
printf "k = %-8s v = %-4s key_list = [%s]\n", $k, $$v, "@$key_list";
}
===============================================================
Could anyone please help me out.

Thanks in Advance
Anand

Search Discussions

  • Anand Jawaji at Aug 23, 2011 at 9:57 am
    Hi All,

    I am working on the below code to traverse through a hash, but it throws an error which states "Can't coerce array into hash at temp.pl line 6."

    Code:
    ===============================================================
    sub hash_walk {
    my $self = shift;

    my ($hash, $key_list, $callback) = @_;

    while (my ($k, $v) = each (%$hash)) {
    push @$key_list, $k;

    if (ref($v) eq 'HASH') {
    $self->hash_walk($v, $key_list, $callback);

    }
    else {
    $callback->($k, \$v, $key_list);

    } pop @$key_list;

    $hash->{$k} = $v;
    }
    }
    my %data = (
    a => {
    ab => 1,
    ac => 2,
    ad => {
    ada => 3,
    adb => 4,
    adc => {
    adca => 5,
    adcb => 6,
    },
    },
    },
    b => 7,
    c => {
    ca => 8,
    cb => {
    cba => 9,
    cbb => 10,
    },
    },
    );
    hash_walk(\%data, [], \&replace_all_val_strings);
    sub replace_all_val_strings {
    my ($k, $v, $key_list) = @_;
    printf "k = %-8s v = %-4s key_list = [%s]\n", $k, $$v, "@$key_list";
    $$v =~ s/oldstr/newstr/;
    printf "k = %-8s v = %-4s key_list = [%s]\n", $k, $$v, "@$key_list";
    }
    ===============================================================
    Could anyone please help me out.

    Thanks in Advance
    Anand
  • Ken Slater at Aug 23, 2011 at 11:20 am

    -----Original Message-----
    From: anand.jawaji@emc.com
    Sent: Tuesday, August 23, 2011 5:57 AM
    To: beginners@perl.org
    Subject: Hash of Hashes - Error

    Hi All,

    I am working on the below code to traverse through a hash, but it
    throws an error which states "Can't coerce array into hash at temp.pl
    line 6."

    Code:
    ===============================================================
    sub hash_walk {
    Why do you have a shift here? $self usually indicates you are calling an
    object method which you are not doing here. Get rid of this shift.
    Looks like you were cutting and pasting some object-oriented code.
    my $self = shift;

    my ($hash, $key_list, $callback) = @_;

    while (my ($k, $v) = each (%$hash)) {
    push @$key_list, $k;

    if (ref($v) eq 'HASH') {
    Why do you use $self? Again hash_walk is not an object method. Just call
    hash_walk.
    $self->hash_walk($v, $key_list, $callback);

    }
    else {
    $callback->($k, \$v, $key_list);

    } pop @$key_list;

    $hash->{$k} = $v;
    }
    }
    my %data = (
    a => {
    ab => 1,
    ac => 2,
    ad => {
    ada => 3,
    adb => 4,
    adc => {
    adca => 5,
    adcb => 6,
    },
    },
    },
    b => 7,
    c => {
    ca => 8,
    cb => {
    cba => 9,
    cbb => 10,
    },
    },
    );
    hash_walk(\%data, [], \&replace_all_val_strings);
    sub replace_all_val_strings {
    my ($k, $v, $key_list) = @_;
    printf "k = %-8s v = %-4s key_list = [%s]\n", $k, $$v,
    "@$key_list";
    $$v =~ s/oldstr/newstr/;
    printf "k = %-8s v = %-4s key_list = [%s]\n", $k, $$v,
    "@$key_list";
    }
    ===============================================================
    Could anyone please help me out.

    Thanks in Advance
    Anand
    HTH, Ken
  • Shlomi Fish at Aug 23, 2011 at 11:39 am
    Hi Anand,

    On Tue, 23 Aug 2011 05:57:02 -0400
    wrote:
    Hi All,

    I am working on the below code to traverse through a hash, but it throws an
    error which states "Can't coerce array into hash at temp.pl line 6."
    First of all, let me note that the indentation on that code is inconsistent and
    erratic. But I was able to fix it by importing it into Vim and using the
    "=" key (= "format") and some manual tweaks. Here is the correct version:

    [CODE]
    #!/usr/bin/perl

    use strict;
    use warnings;

    sub hash_walk {
    my $self = shift;

    my ($hash, $key_list, $callback) = @_;

    while (my ($k, $v) = each (%$hash)) {
    push @$key_list, $k;

    if (ref($v) eq 'HASH') {
    $self->hash_walk($v, $key_list, $callback);
    }
    else {
    $callback->($k, \$v, $key_list);
    }

    pop @$key_list;

    $hash->{$k} = $v;
    }
    }

    my %data = (
    a => {
    ab => 1,
    ac => 2,
    ad => {
    ada => 3,
    adb => 4,
    adc => {
    adca => 5,
    adcb => 6,
    },
    },
    },
    b => 7,
    c => {
    ca => 8,
    cb => {
    cba => 9,
    cbb => 10,
    },
    },
    );

    hash_walk(\%data, [], \&replace_all_val_strings);

    sub replace_all_val_strings {
    my ($k, $v, $key_list) = @_;
    printf "k = %-8s v = %-4s key_list = [%s]\n", $k, $$v, "@$key_list";
    $$v =~ s/oldstr/newstr/;
    printf "k = %-8s v = %-4s key_list = [%s]\n", $k, $$v, "@$key_list";
    }
    [/CODE]

    Now after I did that, I used the perl debugger ("perl -d") to debug the code
    (see http://perl-begin.org/topics/debugging/ ), and realised that the problem
    was that hash_walk expects 4 arguments (including "$self" which is the object
    handle), while it is only given 3 in the initial call, which fails.

    Do you need the "$self" or is there a good reason for that? If you do, read the
    Object Oriented programming resources at
    http://perl-begin.org/topics/object-oriented/ , because otherwise it's just
    cargo-cult programming.

    Also see:

    http://perl-begin.org/tutorials/bad-elements/

    Regards,

    Shlomi Fish

    --
    -----------------------------------------------------------------
    Shlomi Fish http://www.shlomifish.org/
    First stop for Perl beginners - http://perl-begin.org/

    Trying to block Internet pornography is like climbing a waterfall and trying
    to stay dry. (— one of Shlomi Fish’s Internet Friends)

    Please reply to list if it's a mailing list post - http://shlom.in/reply .
  • Anand Jawaji at Aug 23, 2011 at 11:55 am
    Thanks a lot for the suggestions and solution.

    Regards,
    Anand

    -----Original Message-----
    From: Shlomi Fish
    Sent: Tuesday, August 23, 2011 5:09 PM
    To: Jawaji, Anand
    Cc: beginners@perl.org
    Subject: Re: Hash of Hashes - Error

    Hi Anand,

    On Tue, 23 Aug 2011 05:57:02 -0400
    wrote:
    Hi All,

    I am working on the below code to traverse through a hash, but it throws an
    error which states "Can't coerce array into hash at temp.pl line 6."
    First of all, let me note that the indentation on that code is inconsistent and
    erratic. But I was able to fix it by importing it into Vim and using the
    "=" key (= "format") and some manual tweaks. Here is the correct version:

    [CODE]
    #!/usr/bin/perl

    use strict;
    use warnings;

    sub hash_walk {
    my $self = shift;

    my ($hash, $key_list, $callback) = @_;

    while (my ($k, $v) = each (%$hash)) {
    push @$key_list, $k;

    if (ref($v) eq 'HASH') {
    $self->hash_walk($v, $key_list, $callback);
    }
    else {
    $callback->($k, \$v, $key_list);
    }

    pop @$key_list;

    $hash->{$k} = $v;
    }
    }

    my %data = (
    a => {
    ab => 1,
    ac => 2,
    ad => {
    ada => 3,
    adb => 4,
    adc => {
    adca => 5,
    adcb => 6,
    },
    },
    },
    b => 7,
    c => {
    ca => 8,
    cb => {
    cba => 9,
    cbb => 10,
    },
    },
    );

    hash_walk(\%data, [], \&replace_all_val_strings);

    sub replace_all_val_strings {
    my ($k, $v, $key_list) = @_;
    printf "k = %-8s v = %-4s key_list = [%s]\n", $k, $$v, "@$key_list";
    $$v =~ s/oldstr/newstr/;
    printf "k = %-8s v = %-4s key_list = [%s]\n", $k, $$v, "@$key_list";
    }
    [/CODE]

    Now after I did that, I used the perl debugger ("perl -d") to debug the code
    (see http://perl-begin.org/topics/debugging/ ), and realised that the problem
    was that hash_walk expects 4 arguments (including "$self" which is the object
    handle), while it is only given 3 in the initial call, which fails.

    Do you need the "$self" or is there a good reason for that? If you do, read the
    Object Oriented programming resources at
    http://perl-begin.org/topics/object-oriented/ , because otherwise it's just
    cargo-cult programming.

    Also see:

    http://perl-begin.org/tutorials/bad-elements/

    Regards,

    Shlomi Fish

    --
    -----------------------------------------------------------------
    Shlomi Fish http://www.shlomifish.org/
    First stop for Perl beginners - http://perl-begin.org/

    Trying to block Internet pornography is like climbing a waterfall and trying
    to stay dry. (— one of Shlomi Fish’s Internet Friends)

    Please reply to list if it's a mailing list post - http://shlom.in/reply .
  • AKINLEYE at Aug 24, 2011 at 11:27 am
    When you shift off a variable you pop it out of the argument . Just try and
    get the first variable of the argument another way by copying to an array
    first or something .

    from perldoc
    Shift :
    Shifts the first value of the array off and returns it, shortening the array
    by 1 and moving everything down. If there are no elements in the array,
    returns the undefined value. If ARRAY is omitted, shifts the @_ array within
    the lexical scope of subroutines and formats,


    On Tue, Aug 23, 2011 at 10:23 AM, wrote:

    Hi All,

    I am working on the below code to traverse through a hash, but it throws an
    error which states "Can't coerce array into hash at temp.pl line 6."

    Code:
    ===============================================================
    sub hash_walk {
    my $self = shift;

    my ($hash, $key_list, $callback) = @_;

    while (my ($k, $v) = each (%$hash)) {
    push @$key_list, $k;

    if (ref($v) eq 'HASH') {
    $self->hash_walk($v, $key_list, $callback);

    }
    else {
    $callback->($k, \$v, $key_list);

    } pop @$key_list;

    $hash->{$k} = $v;
    }
    }
    my %data = (
    a => {
    ab => 1,
    ac => 2,
    ad => {
    ada => 3,
    adb => 4,
    adc => {
    adca => 5,
    adcb => 6,
    },
    },
    },
    b => 7,
    c => {
    ca => 8,
    cb => {
    cba => 9,
    cbb => 10,
    },
    },
    );
    hash_walk(\%data, [], \&replace_all_val_strings);
    sub replace_all_val_strings {
    my ($k, $v, $key_list) = @_;
    printf "k = %-8s v = %-4s key_list = [%s]\n", $k, $$v, "@$key_list";
    $$v =~ s/oldstr/newstr/;
    printf "k = %-8s v = %-4s key_list = [%s]\n", $k, $$v, "@$key_list";
    }
    ===============================================================
    Could anyone please help me out.

    Thanks in Advance
    Anand


    --
    Akinleye Adedamola
  • Mike McClain at Aug 25, 2011 at 5:38 pm
    <snip>
    On Tue, Aug 23, 2011 at 10:23 AM, wrote:
    I am working on the below code to traverse through a hash, but it throws an
    error which states "Can't coerce array into hash at temp.pl line 6."

    Code:
    ===============================================================
    sub hash_walk {
    my $self = shift;
    my ($hash, $key_list, $callback) = @_;
    while (my ($k, $v) = each (%$hash)) {
    push @$key_list, $k;
    if (ref($v) eq 'HASH') {
    $self->hash_walk($v, $key_list, $callback);
    }
    else {
    $callback->($k, \$v, $key_list);
    } pop @$key_list;
    $hash->{$k} = $v;
    }
    } <snip>
    hash_walk(\%data, [], \&replace_all_val_strings);
    sub replace_all_val_strings {
    my ($k, $v, $key_list) = @_;
    printf "k = %-8s v = %-4s key_list = [%s]\n", $k, $$v, "@$key_list";
    $$v =~ s/oldstr/newstr/;
    printf "k = %-8s v = %-4s key_list = [%s]\n", $k, $$v, "@$key_list";
    }
    I couldn't see any point in '@key_list' and am less comfortable with OO
    than I would like to be but unless I missed something I think this does
    what you're asking after you add '$self' back in.

    my %foods = ( fruit => { qw / apple 1 banana 2 pear 3 / },
    nuts => { pecan => 10, walnut => 20 },
    );

    sub hash_walk
    { my ($hash, $callback) = @_;
    while (my ($k, $v) = each (%$hash))
    { if (ref($v) eq 'HASH')
    { hash_walk($v, $callback);
    }
    else
    { $callback->($k, \$v);
    }
    $hash->{$k} = $v;
    }
    }

    sub replace_all_val_strings
    { my ($k, $v) = @_;
    my $new = ++$$v;
    $$v =~ s/$$v/$new/;
    }

    use Data::Dumper;
    print Dumper \%foods;
    hash_walk(\%foods, \&replace_all_val_strings);
    print Dumper \%foods;

    HTH,
    Mike
    --
    Satisfied user of Linux since 1997.
    O< ascii ribbon campaign - stop html mail - www.asciiribbon.org

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupbeginners @
categoriesperl
postedAug 23, '11 at 9:23a
activeAug 25, '11 at 5:38p
posts7
users5
websiteperl.org

People

Translate

site design / logo © 2021 Grokbase