Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

invoked "break" outside of a loop

394 views
Skip to first unread message

Russell Trleleaven

unread,
Sep 21, 2006, 9:41:03 PM9/21/06
to
set numbers [ list 0 1 2 3 4 5 6 7 8 9 ]
proc foo {} {
#return break
#uplevel break
#namespace eval :: break
return -code break
}
foreach number $numbers {
if { $a == 3 } { foo }
puts $a
}

return break in foo gets me "invoked "break" outside of a loop"
uplevel break does the same.
namespace eval :: break does the same.
return -code break does what I want.

Should any of the first three approaches work like the fourth?

Sincerely,

ru...@else.net

Bryan Oakley

unread,
Sep 21, 2006, 10:27:49 PM9/21/06
to

No.


--
Bryan Oakley
http://www.tclscripting.com

Andreas Leitgeb

unread,
Sep 22, 2006, 3:14:18 AM9/22/06
to
Russell Trleleaven <ru...@else.net> wrote:
> set numbers [ list 0 1 2 3 4 5 6 7 8 9 ]
> proc foo {} {
> #return break
> #uplevel break
> #namespace eval :: break
> return -code break
> }
> foreach number $numbers {
> if { $a == 3 } { foo }
> puts $a
> }
> return break in foo gets me "invoked "break" outside of a loop"

I don't believe. I rather believe that this would let
the loop run to 9 without breaking at 3.
perhaps you actually tried "return [break]" or just "break"
alone, which indeed would both lead to the error you wrote.

return -code break
is the right way to do it, since you want your procedure
foo (seen from outside) behave like the "break" command.

Gerald W. Lester

unread,
Sep 22, 2006, 3:40:36 PM9/22/06
to

Funny, when I run the above code I get:

can't read "a": no such variable

Now if I run:

proc foo {} {
#return break
#uplevel break
#namespace eval :: break
return -code break
}

foreach a $numbers {


if { $a == 3 } { foo }
puts $a
}

I get:
0
1
2

with no error.
--
+--------------------------------+---------------------------------------+
| Gerald W. Lester |
|"The man who fights for his ideals is the man who is alive." - Cervantes|
+------------------------------------------------------------------------+

Russell Trleleaven

unread,
Sep 22, 2006, 10:14:56 PM9/22/06
to

Yes I made an error
Sorry to belabor the point but I was hoping someone would explain why
"break"
"uplevel break"
and
"namespace eval :: break"
don't work like I thought they might.

Sincerely,

ru...@else.net


Gerald W. Lester

unread,
Sep 23, 2006, 1:32:50 AM9/23/06
to

Maybe if you explained why you would think that they would work we may be
able to tell you where you are going wrong.

Darren New

unread,
Sep 24, 2006, 12:59:56 PM9/24/06
to
Russell Trleleaven wrote:
> Sorry to belabor the point but I was hoping someone would explain why
> "break"
> "uplevel break"
> and
> "namespace eval :: break"
> don't work like I thought they might.

As you've learned, [break] is simply a return with a special code
attached. Hence, when you invoke [break], it invokes a command that
returns that special code, which is caught inside your proc, which leads
to the error. I.e., the proc is converting the return from [break] into
a different type of return, since [break] is invoked several levels down
the return stack from the [for] loop.

For example...

proc AA {} {
BB
puts "got here AA"
|

proc BB {} {
if {[catch {
uplevel "set x 0"
}]} { puts "caught something" }
puts "got here BB"
}

Now, given that [set x 0] there return no error, nothing prints.

Were the [set x 0] to be replaced with an error call, you would expect
the catch to catch it, yes?

Hence, since [break] is simply a kind of error, that error return is
returned to the caller for use in [catch]. Since there is no [catch], it
propagates up to the environment of the proc, where proc is about to
return, and says "Hey, why are you throwing a [break] without an
appropriate [catch]?"

Does that help?

--
Darren New / San Diego, CA, USA (PST)
Just because you find out you are
telepathic, don't let it go to your head.

0 new messages