in reply to Iterating over verbatim hash reference
That's why the for syntax was extended in perl6
for %hash.kv -> my $key, $val { say "$key corresponds to $val"; }
Me myself I would love to have a real macro mechanism to solve this properly in perl5, anyway I can suggest you some code to simulate it at least in a functional way
use strict; use warnings; { my %lists; sub deal { my $aref=shift; my $id= \$_[0]; #print $aref,$id; $lists{$id}=$aref if (! exists $lists{$id} ); if (@{$lists{$id}}){ for(@_) { $_=shift @{$lists{$id}}; } return 1; # could be extended to # * iteration counter # * remaining list-elements # * a list of all of these } else { delete $lists{$id}; return 0; } } } $\="\n"; #--------- here we go while (deal [1..9] => my ($a,$b,$c) ){ print $a,$b,$c; while (deal [a=>1,b=>2] => my ($a,$b) ){ print $a,$b; } } #--------- print "EXIT"; __DATA__ 123 a1 b2 456 a1 b2 789 a1 b2 EXIT
I'm not sure if it works prior to 5.10, IMHO there was an issue about "late" my declarations.
Some things to note:
Other approaches¹ solving the repeated LIST creation may be to split functionality onto two functions deal and to such that either
for (deal(LIST);to(VARS)) { ... }
or
while ( deal(LIST) .. to(VARS) ) { ... }
work! (But error-handling becomes trickier)
In the latter correct return values would make the flip-flop operator (scalar ..) build the list only once!
Cheers Rolf
UPDATES:
¹) thats really complicated to realize avoiding a nesting mess, because it's not possible to identify from which codeposition to() is called, the linenumber in caller is not sufficent.
²) maybe the best solution! The call syntax for iterating over a literal hash would be
Please note, no (fat) comma needed, because now we are passing code returning a list NOT a hashref! That's analogous to map and grep's syntax.while( deal {a=>1,b=>2} my($k,$v) ) {..}
|
---|