http://www.perlmonks.org?node_id=248807


in reply to Re: Surpised by foreach iterator limitation
in thread Surpised by foreach iterator limitation

I thought the last paragraph of my post made it clear but perhaps not. I had an involved sub (actually subroutine generator) for validating data. It takes as it's argument a hash. The sub references this in may places. I wanted to refactor it to take multiple arguments for each call. Currently it expects one piece of data. I figured the easiest way and least likely way to intruduce bugs would be to wrap the code in a loop. For example
sub example { # Expects argument data that is a single value my %p = (@_); # return if $p{required} && !$p{data}; Do stuff that references $p{data}... return 1; # OK } my $value = 10; if ( example(data=>$value, minval=>5, maxval=>10){ print "$value is OK!\n"; }else{ die "$value is naughty!"; } Now let's say I want to extended it to take multiple values I thought the easiest way would be to do this. sub example { my %p = (@_); # my @data = UNIVERSAL::isa($p{data},'ARRAY') ? @{$p{data}} : ($p{ +data}); foreach $p{data} (@data){ return if $p{required} && !$p{data}; Do stuff that references $p{data}... } return 1; # OK }
It did not work.

This can be solved in a million simple ways such as using a lexical for the iterator and simply$hash{key} = $iterator_variable as the first statement in the loop.) and I am not looking for a fix. I was simply suprised the Perl could not parse this.

-Lee

"To be civilized is to deny one's nature."

Replies are listed 'Best First'.
Re3: Surpised by foreach iterator limitation
by dragonchild (Archbishop) on Apr 08, 2003 at 17:18 UTC
    Explain to me why this wouldn't work:
    sub exampl { my %p = @_; my @data = UNIVESAL::isa($p{data}, 'ARRAY') ? @{$p{data}} : ( $p{data} ); foreach my $datum (@data) { return if $p{required} && !$datum; # Do stuff that references $datum } return 1; # Everything is OK }
    The point here is that you're stuck in the mode of "I have to reference things the same way". Much better is to say "I have an array of stuff. Let's work with that array."

    Remember - You used to call it $p{data} because it was a member of that hash. Now, it's not. So, don't call it that. Embrace the refactoring goodness.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

    Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

      There is some misunderstanding here. Parts of the information regarding what I was trying to accomplish were spread out over subsequent posts but many are missing the one point since the first thread. I know why this doesn't work (once I tried it) and I know a million ways to fix it, yet I was suprised that Perl cannot use any lvalue in the iterator slot. Which I wish I named this thread :)

      The reason I tried it in the first place instead of just abondoning $p{data} was that the routine and some called by it expect to be able to reference _PARAMETER_ in the user defined error messages. The error messages replace _NAME_ with $p{NAME} using a regex which is why I did not want to refactor it. That means for the current parameter it must be set or everything retooled. I tried to fix it in the laziest and safest way which did not work which was fine because I went the second laziest way.
      for my $data (@data){ $p{data} = $data; ... }


      -Lee

      "To be civilized is to deny one's nature."