Consider this example:
proc show_invocation {} { return [info level -1] } proc a args { puts "Beginning of a." puts [show_invocation] } proc b args { a x y z } proc c args { b 1 2 3 } c skip-to-my-lou
It has output
Beginning of a. a x y z
In English words, this illustrates that a proc can report on the command-line which invoked it. In particular, this provides a base for introspection on the proc call-stack, coded in "Print proc sequence", "A basic debugger", "List the call stack", and perhaps elsewhere.
Exactly that's the way the OO system obj works: an object is a reference to the base procedure called _root-object_, and is created by namespace import ::obj::class::${classname}::_root-object_, then renamed to something line ::obj::inst::new-name''. The reference is located in a namespace ::obj::inst; the name originally called is used as object identifier.
Example:
% set c ::obj::inst::4 % namespace origin $c ::obj::class::curve::_root-object_ % sourceCode $c proc ::obj::class::curve::_root-object_ {{method ::return} args} { $method [lindex [::info level 0] 0] {*}$args } %
There's more, though: with 8.5, it becomes possible to write
package require Tcl 8.5 proc show_complete_invocation {} { array set frame [info frame -2] # Memory leak ahoy! In non-toy code, the file # handle deserves its [close]. set lines [split [read [open $frame(file)]] \n] return [lindex $lines [expr $frame(line) -1]] } proc a args { puts "Beginning of a." puts [show_complete_invocation] } proc b args { a x y z set x [a b c d] } proc c args { b 1 2 3 } c skip-to-my-lou
The output of this script is
Beginning of a. a x y z Beginning of a. set x [a b c d]
While this is a bit fragile, in that it requires a few more lines to handle dynamic proc definitons, and other complications, it should at least hint at the possibilities of this sort of introspection.
enter categories here |
---|