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

Hi, I need some help doing something like this: I have an array of hash references. I need to loop through them and add a new key based on a condition. I have pasted the code that I use below. What I observe is that none of the hash ref have the 'supported' key after I come out of the function. So, I guess I am doing something wrong. What's the right way to achieve this ? Thanks
sub validate_properties { my $properties = shift; for my $prop (@{$properties}) { if (is_supported($prop)) { $prop->{supported} = 1; } else { $prop->{supported} = 0; } return $properties; } }
PS: Updated the code.

Replies are listed 'Best First'.
Re: Looping through an array of hashrefs
by choroba (Cardinal) on Sep 24, 2014 at 13:21 UTC
    The code you posted has syntax errors (missing parentheses around the if-condition, missing right curly brace). When I tried to fix them, all worked correctly:
    #!/usr/bin/perl use warnings; use strict; use Data::Dumper; sub validate_properties { my $properties = shift; for my $prop (@{$properties}) { if (.5 < rand) { $prop->{supported} = 1; } else { $prop->{supported} = 0; } } return $properties } print Dumper validate_properties([map +{ id => $_ }, 1 .. 5]);

    Output:

    So, please show the real code that exhibits the problem.

    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
      # a simplified approach with less clutter you might find useful.. To me, reducing code I have to maintain 50% makes my job 1/2 as difficult.. You pass in an arrayref you didn't need any returned val I don't think....
      sub validate_properties { for ( @{$_[0]} ) { $_->{supported} = 0; $_->{supported}++ if .5 < rand; } }

        In that case, why not eliminate half the code in that loop?:

        sub validate_properties { for ( @{$_[0]} ) { $_->{supported} = .5 < rand; } }

        Or even inline it as: $_->{supported} = .5 < rand for @array;?

        Based on the (modified) original post, it should be $_->{supported} = isSupported($_) for @properties; rather than random.
        I don't see how saving the results of an isSupported() test could be described as "validating properties", but I suppose that's a lack of context speaking.

Re: Looping through an array of hashrefs
by LanX (Saint) on Sep 24, 2014 at 13:25 UTC
    Generally, please show dumped sample data before and after the run to make life easier for us!

    If that's an AoH, then $prop must be a hashref, do you really need to call is_supported($prop) then?

    This logic looks dubious, give us more insight please.

    Cheers Rolf

    (addicted to the Perl Programming Language and ☆☆☆☆ :)

    update

    choroba is of course right about the syntax errors!

    ...another wasted post for someone too lazy to post compilable code... :-/

Re: Looping through an array of hashrefs
by SuicideJunkie (Vicar) on Sep 24, 2014 at 15:43 UTC

    What you need to do is step through that code yourself and see what it does. If you don't see the problem mentally, then add print statements all over.

    sub validate_properties { my $properties = shift; for my $prop (@{$properties}) { if (is_supported($prop)) { $prop->{supported} = 1; } else { $prop->{supported} = 0; } return $properties; } }
    1. (line 2) Shift in the properties array ref. OK.
    2. (line 3) Start loop. First element of properties is $prop. Righto.
    3. (lines 4-8) Set $prop->{supported}. Mmhmm.
    4. (line 9) Exit the function. Er...
    5. (line 10) Goto line 3, and finish the rest of the elements. Ooops, we never get here, because we exited the function already.