0

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

3
  • 2
    As of now, there is no in-built mechanism for this. You can explicitly use unset command to achieve the same after the foreach loop. Commented Jun 8, 2016 at 8:33
  • Yeah, that's what I am using now (clutter minimization). Commented Jun 8, 2016 at 8:35
  • Or, you can override the foreach command's behavior with rename and do the unset operation for you. Commented Jun 8, 2016 at 8:38

2 Answers 2

1

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

Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.