Reputation: 3103
See Tcl shell code & results below:
% foreach a { 1 2 3 4 5 } { puts $a }
1
2
3
4
5
% puts $a
5
It would appear that variable a stays in the memory... In Perl, for example one can use:
foreach my $a
And have $a exist just during the looping. in Ruby, one can use closures:
[1,2,3,4,5].each{|a| puts a.to_s() }
In order to achieve the same.
Is there an elegant way to this in Tcl?
Thanks
Upvotes: 0
Views: 195
Reputation: 13252
You can iterate within a closure:
apply {vals {foreach a $vals {puts $a}}} {1 2 3 4 5}
alternatively you can make the body a parameter (in which case the looping variable’s name should be a parameter too):
apply {{varName vals body} {foreach $varName $vals $body}} a {1 2 3 4 5} {puts $a}
If you call this myForeach
or something, it looks less cumbersome:
set myForeach {{varName vals body} {foreach $varName $vals $body}}
apply $myForeach a {1 2 3 4 5} {puts $a}
You can also make this an interpreter macro:
set myForeach {{varName vals body} {foreach $varName $vals $body}}
interp alias {} myForeach {} apply $myForeach
myForeach a {1 2 3 4 5} {puts $a}
Documentation: apply, foreach, interp package, interp, puts, set
Upvotes: 1
Reputation: 137587
This is not the current semantics of foreach
, and this is extremely unlikely to change in the near future as it would have a severe impact on many people's existing code. In particular, many people currently use:
foreach {a b c d} $someList break
Instead of doing:
lassign $someList a b c d
Because that was what worked in Tcl 8.4 and before and they've not updated their coding style since.
Upvotes: 0