Gentlemen, please:
--------------------
#!/usr/bin/env tclsh
proc outside {} {
proc inside {} {
return "deep thoughts"
}
inside
return "shallow thoughts"
}
puts [outside]
--------------------
How do I get the outside proc to return "deep thoughts"?
--
Luc
On Friday, November 4, 2022 at 7:37:09 AM UTC+1, Luc wrote:
Gentlemen, please:
--------------------
#!/usr/bin/env tclsh
proc outside {} {
proc inside {} {
return "deep thoughts"
}
inside
return "shallow thoughts"
}
puts [outside]
--------------------
How do I get the outside proc to return "deep thoughts"?
Perhaps you should explain to us what you want to do?
On Friday, November 4, 2022 at 7:37:09 AM UTC+1, Luc wrote:
Gentlemen, please:
--------------------
#!/usr/bin/env tclsh
proc outside {} {
proc inside {} {
return "deep thoughts"
}
inside
return "shallow thoughts"
}
puts [outside]
--------------------
How do I get the outside proc to return "deep thoughts"?
--
Luc
You can do:
proc outside {} {
proc inside {} {
return "deep thoughts"
}
return [inside]
# return "shallow thoughts" --- wil not be reached
}
puts [outside]
But you should note that by putting the definition of "inside" inside the body of "outside", it is created each time "outside" is called.
Perhaps you should explain to us what you want to do?
Regards,
Arjen
No, that doesn't work either. I forgot I am prototyping the whole thing
as an independent creature, but it's supposed to be a proc once it's ready. So it can't just exit. The entire application would die with it.
Never let anyone ask me to code for airports or railways.
Hey, you know what works?
if {[condition ismet $_foobar]} {puts "Yes!"; exit}
But I'm afraid my tcler license will be revoked if I do that... :-)
Seriously, though. There must be a more "proper" way.
* Luc <[email protected]>
| I have proc1.
| Inside proc1, there is proc2.
Why is proc2 *inside* proc1?
Usually procs are defined at global scope and not inside other procs
(yes I know, there might be uses for that, but until explained by the OP
I'd rather assume some confusion about basic concepts here).
Gentlemen, please:
--------------------
#!/usr/bin/env tclsh
proc outside {} {
proc inside {} {
return "deep thoughts"
}
inside
return "shallow thoughts"
}
puts [outside]
--------------------
How do I get the outside proc to return "deep thoughts"?
Ralf Fassel <[email protected]> wrote:
Why is proc2 *inside* proc1?
Indeed, an answer to this question is important.
**************************
On Fri, 4 Nov 2022 13:36:14 -0000 (UTC), Rich wrote:
Ralf Fassel <[email protected]> wrote:
Why is proc2 *inside* proc1?
Indeed, an answer to this question is important.
************************
I believe the answer is pretty obvious.
It's a large proc. I need to organize everything in sub functions
inside the function.
...
The return -code return "deep thoughts" idea doesn't work either.
The "deep thoughts" example I posted previously is too simple to reflect
what I have here. I basically need a command that says
STOP EVERYTHING RIGHT NOW, RETURN THIS STRING AND DISAPPEAR
On 11/4/22 09:34, Luc wrote:
**************************
On Fri, 4 Nov 2022 13:36:14 -0000 (UTC), Rich wrote:
Ralf Fassel <[email protected]> wrote:
Why is proc2 *inside* proc1?
Indeed, an answer to this question is important.
************************
I believe the answer is pretty obvious.
It's a large proc. I need to organize everything in sub functions
inside the function.
Ah, you do realize that all procs are globally addressable -- there is
no such thing as a sub function in Tcl.
A Tcl proc, can have another proc declared inside of it -- but that just causes it to be defined/redefined at runtime and it can be called by anyone.
Now a Tcl proc can *call* another function, but that does not make it "inside" nor does it make it a aub function.
...
The return -code return "deep thoughts" idea doesn't work either.
The "deep thoughts" example I posted previously is too simple to reflect what I have here. I basically need a command that says
STOP EVERYTHING RIGHT NOW, RETURN THIS STRING AND DISAPPEAR
You need to combine [info level] with [return] -- please read both
man/help pages in detail and pay close attention to the level option on
the return.
**************************
On Fri, 4 Nov 2022 13:36:14 -0000 (UTC), Rich wrote:
Ralf Fassel <[email protected]> wrote:
Why is proc2 *inside* proc1?
Indeed, an answer to this question is important.
************************
I believe the answer is pretty obvious.
It's a large proc. I need to organize everything in sub functions
inside the function.
I have been quite clear about what I need. Again:
I have proc1.
Inside proc1, there is proc2 and about 20 other procs.
Then proc2 creates widgets AND it calls many other procs in the process.
Multiple widgets may be manipulated until a decision is taken. Each one
of them also calls a number of procs. It's all a matter of organization.
A button in a widget calls proc3.
Then proc 3 also calls a bunch of other procs and meanwhile it may
or may not decide it's time for the big parent proc to return an output.
It's all a matter of organization.
It's 1,900 lines of code. And yes, I'm afraid it may be a little spaghetti here and there. I will improve it later. But this is not the best time to post
more code. Please consider just the description above. The entire code will be
published eventually and I will be very open to criticism, but I can't publish
something that doesn't work.
I was almost sure someone would suggest uplevel, but nobody has and I have tried it on my own, it doesn't seem to work.
The return -code return "deep thoughts" idea doesn't work either.
The "deep thoughts" example I posted previously is too simple to reflect
what I have here. I basically need a command that says
STOP EVERYTHING RIGHT NOW, RETURN THIS STRING AND DISAPPEAR
Ah, you do realize that all procs are globally addressable -- there is
no such thing as a sub function in Tcl.
You need to combine [info level] with [return] -- please read both
man/help pages in detail and pay close attention to the level option on
the return.
This sounds like you need to use wait:
proc proc2 {args} {
### create widgets here
global answer
set answer 0
button .foo -command proc3
}
proc proc3 {} {
# this is bound to button
global answer
incr answer
}
proc proc1 {args} {
proc2
global answer
vwait answer
return $answer
}
**************************
On Fri, 4 Nov 2022 13:36:14 -0000 (UTC), Rich wrote:
Ralf Fassel <[email protected]> wrote:
Why is proc2 *inside* proc1?
Indeed, an answer to this question is important.
************************
I believe the answer is pretty obvious.
It's a large proc. I need to organize everything in sub functions
inside the function.
I have been quite clear about what I need. Again:
The return -code return "deep thoughts" idea doesn't work either.
The "deep thoughts" example I posted previously is too simple to reflect
what I have here. I basically need a command that says
STOP EVERYTHING RIGHT NOW, RETURN THIS STRING AND DISAPPEAR
On Fri, 4 Nov 2022 10:17:17 -0500, Gerald Lester wrote:
Ah, you do realize that all procs are globally addressable -- there is
no such thing as a sub function in Tcl.
I don't understand what you mean.
proc out {} {
proc in {} {
return "deep thoughts"
}
return "shallow thoughts"
}
% puts [out]
shallow thoughts
% puts [in]
invalid command name "in"
while executing
"in"
invoked from within
"puts [in]"
(file "procproc.tcl" line 9)
Compilation failed.
proc "in" only works inside "out."
That is not my idea of "globally addressable."
The entire thing is in a proc. If it returns, it should be extinguished immediately after printing output, shouldn't it?
Something is broken in your Tcl interpreter (or you did not actually
run the same code you posted):
$ rlwrap tclsh
proc out {} {
proc in {} {
return "deep thoughts"
}
return "shallow thoughts"
}
% puts [out]
shallow thoughts
% puts [in]
deep thoughts
%
and run it. The output will be:
Hello from a!
hello from b!
Yes, because [puts] has a way of piercing through armour.
Now, if only I could do that with [return]...
On Fri, 4 Nov 2022 10:17:17 -0500, Gerald Lester wrote:
Ah, you do realize that all procs are globally addressable -- there is
no such thing as a sub function in Tcl.
I don't understand what you mean.
proc out {} {
proc in {} {
return "deep thoughts"
}
return "shallow thoughts"
}
% puts [out]
shallow thoughts
% puts [in]
invalid command name "in"
while executing
"in"
invoked from within
"puts [in]"
(file "procproc.tcl" line 9)
Compilation failed.
proc "in" only works inside "out."
That is not my idea of "globally addressable."
I think he means this:
Create a file like:
============
#!/usr/local/bin/tclsh8.6
proc a {} {
puts "Hello from a!"
proc b {} {
puts "hello from b!"
}
}
a
b
============
and run it. The output will be:
Hello from a!
hello from b!
It is not. As defining a proc, inside another proc, is only rarely
done, and even then, generally for very advanced "dynamic code
generation" reasons. None of which your example, nor initial question, implied was happening.
By defining a proc, inside another proc, you are repeating the
creation of that 'inner' proc every time you execute the outer proc
(which if the outer proc is executed multiple times can result in a
rather significant performance loss).
That is also not how the procs are organized once defined. Without any namespace qualifiers, they are all created, at the same level, in the
current namespace.
On Fri, 04 Nov 2022 15:45:05 +0000, Robert Heller wrote:
This sounds like you need to use wait:
proc proc2 {args} {
### create widgets here
global answer
set answer 0
button .foo -command proc3
}
proc proc3 {} {
# this is bound to button
global answer
incr answer
}
proc proc1 {args} {
proc2
global answer
vwait answer
return $answer
}
************************
I suspected for some time that vwait would be the answer. But I don't know how to use it. There are parts of Tcl that I never learned properly.
Your method with vwait kind of works.
proc bigproc {} {
...
}
puts [bigproc]
The expected output prints, but the... um, application doesn't close.
That I could have achieved with puts.
The entire thing is in a proc. If it returns, it should be extinguished immediately after printing output, shouldn't it?
No. Wish (or package require Tk), does not "exit" upon EOF on the .tcl
file. It does not exit until either the exit command is invoked or the
main toplevel (.) is destroyed. So, what you really want bound to your "exit" button is:
proc exitButton {} {
# print the answer
puts "This is the answer"
# then exit
exit
}
Or with a pure GUI environment (with no console screen or shell window):
proc exitButton {} {
# put up a message dialog box.
tk_messageBox -icon info -message "This is the answer" -type ok
# when the user clicks OK, exit the program.
exit
}
**************************
On 4 Nov 2022 17:00:34 GMT, [email protected] (Ted Nolan ) wrote:
I think he means this:
Create a file like:
============
#!/usr/local/bin/tclsh8.6
proc a {} {
puts "Hello from a!"
proc b {} {
puts "hello from b!"
}
}
a
b
============
and run it. The output will be:
Hello from a!
hello from b!
Yes, because [puts] has a way of piercing through armour.
Now, if only I could do that with [return]...
On Fri, 4 Nov 2022 16:48:50 -0000 (UTC), Rich wrote:
It is not. As defining a proc, inside another proc, is only rarely
done, and even then, generally for very advanced "dynamic code
generation" reasons. None of which your example, nor initial question, implied was happening.
Are you saying I should remove everything from its all-enveloping proc
and provide the entire idea as a plain page (though still with procs)
and let people just [source] it instead of running it as a proc?
I admit I have thought about that.
By defining a proc, inside another proc, you are repeating the
creation of that 'inner' proc every time you execute the outer proc
(which if the outer proc is executed multiple times can result in a
rather significant performance loss).
Yes, that's intended. All those procs are necessary every time the big proc is run. The big proc won't work without them.
The big proc will not be executed multiple times. Well, it will, but not
in rapid sequence. It's a tool that people will launch occasionally.
I don't believe any of those procs is CPU or memory intensive.
I believe everything I'm doing is pretty regular except that I wrapped
the whole package in an all-encompassing proc.
For example, take /usr/share/tcltk/tk8.6/bgerror.tcl. It has seven procs.
Now put that entire page inside one parent proc. That's what I did.
Sort of. That's all.
That is also not how the procs are organized once defined. Without any namespace qualifiers, they are all created, at the same level, in the current namespace.
That one statement is not accurate. As it turns out, EVERYTHING I'm doing
has its own namespace so nothing in it will clash with anything else in whatever application that may come to adopt it. It's one big proc inside
one single namespace. ALL procs and variables reside in that namespace.
Gentlemen, please:
--------------------
#!/usr/bin/env tclsh
proc outside {} {
proc inside {} {
return "deep thoughts"
}
inside
return "shallow thoughts"
}
puts [outside]
--------------------
How do I get the outside proc to return "deep thoughts"?
**************************
On Fri, 4 Nov 2022 17:16:53 -0000 (UTC), Rich wrote:
Something is broken in your Tcl interpreter (or you did not actually
run the same code you posted):
$ rlwrap tclsh
proc out {} {
proc in {} {
return "deep thoughts"
}
return "shallow thoughts"
}
% puts [out]
shallow thoughts
% puts [in]
deep thoughts
%
True.
I think I ran it the other way around:
puts [in]
puts [out]
The simple answer of course is
proc outside {} {
return [inside]
}
proc inside {} {
return "deep thoughts"
}
outside
=> deep thoughts
But I suspect this is not what you're after...
R'
On Fri, 04 Nov 2022 17:35:27 +0000, Robert Heller wrote:
No. Wish (or package require Tk), does not "exit" upon EOF on the .tcl file. It does not exit until either the exit command is invoked or the
main toplevel (.) is destroyed. So, what you really want bound to your "exit" button is:
proc exitButton {} {
# print the answer
puts "This is the answer"
# then exit
exit
}
Or with a pure GUI environment (with no console screen or shell window):
proc exitButton {} {
# put up a message dialog box.
tk_messageBox -icon info -message "This is the answer" -type ok
# when the user clicks OK, exit the program.
exit
}
I can't use exit. It's a proc. It's meant to be used inside a parent application. Calling [exit] will kill the parent application.
On Fri, 4 Nov 2022 10:17:17 -0500, Gerald Lester wrote:
Ah, you do realize that all procs are globally addressable -- there is
no such thing as a sub function in Tcl.
I don't understand what you mean.
proc out {} {
proc in {} {
return "deep thoughts"
}
return "shallow thoughts"
}
% puts [out]
shallow thoughts
% puts [in]
invalid command name "in"
while executing
"in"
invoked from within
"puts [in]"
(file "procproc.tcl" line 9)
Compilation failed.
On Fri, 4 Nov 2022 16:48:50 -0000 (UTC), Rich wrote:
It is not. As defining a proc, inside another proc, is only rarely
done, and even then, generally for very advanced "dynamic code
generation" reasons. None of which your example, nor initial question,
implied was happening.
Are you saying I should remove everything from its all-enveloping proc
and provide the entire idea as a plain page (though still with procs)
and let people just [source] it instead of running it as a proc?
I admit I have thought about that.
By defining a proc, inside another proc, you are repeating the
creation of that 'inner' proc every time you execute the outer proc
(which if the outer proc is executed multiple times can result in a
rather significant performance loss).
Yes, that's intended. All those procs are necessary every time the big proc is run. The big proc won't work without them.
The big proc will not be executed multiple times. Well, it will, but not
in rapid sequence. It's a tool that people will launch occasionally.
I don't believe any of those procs is CPU or memory intensive.
I believe everything I'm doing is pretty regular except that I wrapped
the whole package in an all-encompassing proc.
For example, take /usr/share/tcltk/tk8.6/bgerror.tcl. It has seven procs.
Now put that entire page inside one parent proc. That's what I did.
Sort of. That's all.
That is also not how the procs are organized once defined. Without
any namespace qualifiers, they are all created, at the same level,
in the current namespace.
That one statement is not accurate. As it turns out, EVERYTHING I'm doing
has its own namespace so nothing in it will clash with anything else in whatever application that may come to adopt it. It's one big proc inside
one single namespace. ALL procs and variables reside in that namespace.
At Fri, 4 Nov 2022 10:17:17 -0500 Gerald Lester <[email protected]> wrote:
On 11/4/22 09:34, Luc wrote:
**************************
On Fri, 4 Nov 2022 13:36:14 -0000 (UTC), Rich wrote:
Ralf Fassel <[email protected]> wrote:
Why is proc2 *inside* proc1?
Indeed, an answer to this question is important.
************************
I believe the answer is pretty obvious.
It's a large proc. I need to organize everything in sub functions
inside the function.
Ah, you do realize that all procs are globally addressable -- there is
no such thing as a sub function in Tcl.
You can sort of get that with OOP with member functions (eg SNIT, incrTcl, BWidget). You can also use namespaces to "protect" things and avoid problems with name clashes.
A Tcl proc, can have another proc declared inside of it -- but that just
causes it to be defined/redefined at runtime and it can be called by anyone. >>
Now a Tcl proc can *call* another function, but that does not make it
"inside" nor does it make it a aub function.
It sounds like that OP wants to create a class with "private" members (or something like that). Tcl has OOP extensions, but I don't think any implement strickly private (or protected) members or methods (AFAIK). (SNIT doesn't.)
...
The return -code return "deep thoughts" idea doesn't work either.
The "deep thoughts" example I posted previously is too simple to reflect >>> what I have here. I basically need a command that says
STOP EVERYTHING RIGHT NOW, RETURN THIS STRING AND DISAPPEAR
You need to combine [info level] with [return] -- please read both
man/help pages in detail and pay close attention to the level option on
the return.
I suspect that this won't help either. He wants to exit a proc on a button click. The button -command is running at level 0 and the proc is somewhere else (or maybe already exited).
I suspect he really wants tkwait:
proc main {} {
global theanswer
## build widgets and start processing
set theanswer {}
tkwait variable theanswer
return $theanswer
}
And somewhere there is a button with a -command bound to a proc like:
proc buttonpress {} {
global theanswer
set theanswer "This is the answer"
}
| Sysop: | Keyop |
|---|---|
| Location: | Huddersfield, West Yorkshire, UK |
| Users: | 715 |
| Nodes: | 16 (2 / 14) |
| Uptime: | 16:31:45 |
| Calls: | 12,103 |
| Calls today: | 3 |
| Files: | 15,004 |
| Messages: | 6,518,059 |