Sujet : Re: a typeof command for debugging?
De : m.n.summerfield (at) *nospam* gmail.com (Mark Summerfield)
Groupes : comp.lang.tclDate : 22. Jun 2025, 07:50:14
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <1038936$cj4h$1@dont-email.me>
References : 1 2
User-Agent : Pan/0.149 (Bellevue; 4c157ba)
On Sat, 21 Jun 2025 15:51:31 +0200, Christian Gollwitzer wrote:
Am 21.06.25 um 13:16 schrieb Mark Summerfield:
I'd like a `typeof` command for debugging.
I've had a go but only bits of it work.
```
proc typeof x {
if {![catch {[info object class $x] name}]} {
return $name
} else {
if {[string is boolean -strict $x]} {
return bool
[...]
I don't think you can do much better than that, since Tcl is a weakly
typed language (usually referred to as the "EIAS" principle). The only
other thing you can do is peek into the internal cached type, which
shows you the last type that was used on that object (besides string):
(chris) 50 % set a [expr {23*5}]
115 (chris) 51 % tcl::unsupported::representation $a value is a int with
a refcount of 4, object pointer at 0x55d6b8f8b320,
internal representation 0x73:(nil), string representation "115"
Christian
I found that tcl::unsupported::representation says "pure string" for
strings and numbers and bools and lists; it only seems to distinguish
dicts (Tcl 9.0.1).
I've incorporated that but I still have an actual bug. The catch always
returns false (failed) so objects always get returned as list_or_str. Yet,
if I use info object class directly it correctly returns the class name.
So clearly I'm doing something wrong in the catch.
proc typeof x {
# puts "\n[tcl::unsupported::representation $x]"
if {![catch {[info object class $x] name}]} {
return $name
} else {
if {[string is boolean -strict $x]} { return bool }
if {[string is integer -strict $x]} { return int }
if {[string is double -strict $x]} { return real }
if {[string match "value is a dict*" \
[tcl::unsupported::representation $x]]} {
return dict
}
if {[string is list -strict $x]} { return list_or_str }
return str
}
}
In the above the catch always returns false.
set r [Range new 5]
puts "r=$r typeof=[typeof $r]"
puts "r=$r info object class=[info object class $r]"
Outputs:
r=::oo::Obj24 typeof=list_or_str
r=::oo::Obj24 info object class=::Range