On 7/4/07, Mathew Snyder <[EMAIL PROTECTED]> wrote:
>> foreach my $user (keys %tickets) { >> foreach my $env (keys %{ $tickets{$user} }) { >> foreach my $tikID (keys %{ $tickets{$user}{$env} }) { >> foreach my $subject (keys %{ >> $tickets{$user}{$env}{$tikID} }) { > > You're doing the same dereferencing, just getting deeper each time. > You'll save some time if you make some of those into temporary > variables. That fourth nested loop could look more like this, but > possibly with better variable names: > > my $subjects_hash = $envs_hash->{$env}; > foreach my $subject (keys %$subjects_hash) { > Can you explain the reason for skipping the {$id} portion and assigning the {$env} portion to %subjects_hash? The logic eludes me.
Maybe I've put the parts together wrong, or named them poorly. But the general idea is that most references are copied to scalars, so that you don't have to dereference $tickets{$user} as part of every variable you access within four nested loops. That's probably going to give you clearer code, but it will also be faster to execute. The outer loop looks like this: foreach my $user (keys %tickets) { Since there's just one value for $user each time through the loop, $tickets{$user} will have just one value each time through the loop. So instead of doing that hash lookup again and again, we'll keep the result in a scalar. my $users_tix = $tickets{$user}; Since the scalar is declared just inside the loop, its scope ends at the same place that $user's scope ends. So any line of code that used to use $tickets{$user} can now use $users_tix just as well. (If their scopes ended in different places, those two expressions wouldn't always be interchangeable.) Of course, the scalar could have been named $tickets_for_user or $current_users_tickets, or something that does a better job of matching what it's really about. I'm not clear on the nature of the overall task or I'd have more confidence in my choice of name. I hope that the technique is clear enough. So, from now on, whenever we need $tickets{$user}, we can use $users_tix. And we need it in the next nested loop, which used to look like this: foreach my $env (keys %{ $tickets{$user} }) { But now it looks like this: foreach my $env (keys %{ $users_tix }) { Or, because the curly braces are optional around a just-plain-scalar, many people prefer this: foreach my $env (keys %$users_tix) { Using the same trick another level down, we get the easy way to write $tickets{$user}{$env} , which could also be written $tickets{$user}->{$env} : my $users_env = $users_tix->{$env}; The small arrow is optional in $tickets{$user}->{$env} because the other punctuation is sufficient. If there are curly braces or square brackets on both sides of the arrow, or one of each, the small arrow may be omitted. But it reappears in the line of code above; it's mandatory here because there's no longer a "closing" piece of punctuation to its left. And so on. By the time you get to the body of the fourth nested loop, each variable access has become significantly shorter, so each line of code is that much more readable and speedy to execute. Good luck with it! --Tom Phoenix Stonehenge Perl Training -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/