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

for my $k (@required_fields) { StripLTSpace($href->{$k}); $href->{$k} or return DIRTY $row, "ERROR: required field $k not present"; }
I had to manually index into my hashref twice, which is computive intensive, but it would be nice if... oh I think Alias allows me to do this already... no actually it does not appear to make this any easier. What I would like to have is
for my $k :used_as=>$href->{$k} (@required_fields) { StripLTSpace($k); $k or return DIRTY $row, "ERROR: required field $k not present"; }

Carter's compass: I know I'm on the right track when by deleting something, I'm adding functionality... download and use The Emacs Code Browser

Replies are listed 'Best First'.
Re: Will Perl 6 abbreviate this indirection for me?
by bbfu (Curate) on Sep 08, 2003 at 21:22 UTC

    Unless StripLTSpace() is actually using a prototype to get a reference to $href->{$k} (update: which it then modifies), or the values of the hash may be large, you could probably just make a copy of the value:

    for my $k (@required_fields) { my $v = $href->{$k}; StripLTSpace($v); $v or return DIRTY $row, "ERROR: required field $k not present"; }

    If you don't want to make a copy, you can use for's aliasing ability, like so:

    for my $k (@required_fields) { for my $v ($href->{$k}) { StripLTSpace($v); $v or return DIRTY $row, "ERROR: required field $k not present"; } }

    IIRC, the syntax for Perl6 for loops will include the ability to have multiple iterator variables, something similar to:

    for my $k, $v (...) {

    But I'm not sure how you'd write the ... part. The only thing I can think of now is something involving map that's likely to be more expensive than just creating a copy of the value. *shrug*

    Update: Another way to do it:

    for my $k (@required_fields) { my $vr = \$href->{$k}; StripLTSpace($$vr); $$vr or return DIRTY $row, "ERROR: required field $k not present"; }

    Thinking about it further, however, I find it a bit unlikely that doing two hash look-ups rather than one is actually profiling as a bottleneck in your program. Unless there are extenuating circumstances that you haven't detailed, perhaps you should profile the program to determine exactly where the bottlenecks are occuring.

    bbfu
    Black flowers blossom
    Fearless on my breath

Re: Will Perl 6 abbreviate this indirection for me?
by clscott (Friar) on Sep 08, 2003 at 21:30 UTC

    I don't see you second formulation is any more readable.

    I'd usually make a local assignment:

    for my $field (@required_fields) { my $form_value = $href->{$field}; StripLTSpace($form_value); defined $form_value or return DIRTY $row, "ERROR: required field $k not present"; }

    P.S. In your error clause check for the definedness of the value rather that it's truth unless you really know that all of the potential values must evaluate to true in that context.

    --
    Clayton
Re: Will Perl 6 abbreviate this indirection for me?
by adrianh (Chancellor) on Sep 08, 2003 at 22:22 UTC

    You should be able to use Perl 6's given something like this:

    for my $k (@required_fields) { given $href->{$k} { StripLTSpace($_); $_ or return DIRTY $row, "ERROR: required field $k not present +"; }; }
    However, if you're worrying about this sort of thing for efficiency reasons something is seriously wrong somewhere ;-)

      Thanks for the reply.
      If you're worrying about this sort of thing for efficiency reasons something is seriously wrong somewhere
      Actually though, just imagine if each FETCH were tied to something compute intensive. Also, I am very serious about reducing redundancy in my code.

      Carter's compass: I know I'm on the right track when by deleting something, I'm adding functionality... download and use The Emacs Code Browser

        Actually though, just imagine if each FETCH were tied to something compute intensive.

        I can certainly imagine it - however I would still see it as a sign of something being seriously wrong.

        Creating a system where a computationally intensive operation became hidden behind an operation that is traditionally computationally cheap would be a design mistake in my book. It confounds expectations.

        The reduction in redundancy is a fair point, and I wouldn't want to argue with that being a fan of once and only once myself.

Re: Will Perl 6 abbreviate this indirection for me?
by BrowserUk (Patriarch) on Sep 08, 2003 at 23:45 UTC

    The syntax you require is already available, albeit a little obscure.

    my $href; @{ $href }{ 'a' .. 'z' } = 1 .. 26; my @required_fields = qw[ a c e g i k m o q s u w y ]; for my $k ( \( @h{ @required_fields } ) ){ print $$k; } 1 3 5 7 9 11 13 15 17 19 21 23 25

    Note however, that once you make $k an alias to the value, you no longer have access to the related key, so you cannot use it in your error message. This would also be the case with your 'used_as' syntax.

    In order to have both the key and an alias to the value available, you would need to use syntax like

    while( my( $kref, $vref ) = \( each %{ $href } ) ) { print $$kref, ' => ', $$vref; }

    Which achieves this, but the problem is now that you have lost the ability to constrain the keys over which you iterate. About the best you might do in this case is to add a next if .... clause in the loop, but comparing each keys against every entry in your @required_fields array is ludicrous:). So now you might create a lookup (another hash) for just the required keys and grep against that but....:)

    I keep thinging about P6s Pair and Binding operators ==> and <==, and trying to work out in my minds eye how these might be combined with a hash slice to achieve your goal, but whilst I can follow and relish TheDamians exogesies, remembering enough of the syntax and semantics to start trying to put together my own snippets is well beyond me at this stage. Maybe he'll happen by and put us out of our misery!


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
    If I understand your problem, I can solve it! Of course, the same can be said for you.

Re: Will Perl 6 abbreviate this indirection for me?
by Roger (Parson) on Sep 08, 2003 at 23:38 UTC
    Here's my little implementation which uses the perl map and foreach built-in's:

    foreach (map{StripLTSpace($href->{$_})}@required_fields) { print "Error!\n" if ($_ eq undef); }
    In the above code, map will create a list of space stripped hash references based on each element of the required fields, and foreach will then take each element of the generated list and test if there is an undef value in the list (which of cause means missing).

    Now you could split the above into two separate steps, map and then foreach, but I just like to combine them together for fun. he he he...
Re: Will Perl 6 abbreviate this indirection for me?
by dragonchild (Archbishop) on Sep 08, 2003 at 20:47 UTC
    I wish people would actually read the Camel book and not just use it as a reference. Perl5 has been doing what you want for years. Remember - the hard things are simple. Most things aren't impossible ...
    while (my ($k, $v) = each %$href) { StripLTSpace($v); $v or return DIRTY $row, "ERROR: required field $k not present"; }

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

    The idea is a little like C++ templates, except not quite so brain-meltingly complicated. -- TheDamian, Exegesis 6

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

      I don't think that actually does what princepawn wants, as he's iterating over an independant list (@required_fields) that may or may not contain all of the keys in %$href.

      bbfu
      Black flowers blossom
      Fearless on my breath