Version 3 of Inspecting TclOO

Updated 2016-04-15 00:13:46 by Eugene

Tcl's wonderful introspection capabilities extend to TclOO through a profusion of info object and info class subcommands. Yummy! But so many subcommands are a bit tricky to digest .. here's a tool aspect made to assist looking inside:

proc inspect {obj} {
    set obj [uplevel 1 [list namespace which -command $obj]]
    set isa [lmap type {object class metaclass} {
        if {![info object isa $type $obj]} continue
        set type
    }]
    if {"class" in $isa} {
        lappend info {class superclasses} {class mixins} {class filters}
        lappend info {class methods} {class methods}
        lappend info {class variables} {class variables}
    }
    if {"object" in $isa} {
        lappend info {object class} {object mixins} {object filters}
        lappend info {object methods} {object methods}
        lappend info {object variables} {object variables}
        lappend info {object namespace} {object vars} ;#{object commands}
    }
    set result [dict create isa $isa]
    foreach args $info {
        dict set result $args [info {*}$args $obj]
        foreach opt {-private -all} {
            catch {
                dict set result [list {*}$args $opt] [info {*}$args $obj $opt]
            }
        }
    }
    dict filter $result value {?*}
}

proc pdict {d args} {   ;# analogous to parray
    set maxl [::tcl::mathfunc::max {*}[map {string length} [dict keys $d]]]
    dict for {key value} $d {
        puts stdout [format "%-*s = %s" $maxl $key $value]
    }
}

#extend ::oo::InfoClass {
#    proc commands {o args} {
#        map {::namespace tail} [info commands [info object namespace $o]::*]
#    }
#}

If you have ensemble extend, the info object commands extension might be useful.

Here's what it has to say about our two favourite objects:

% pdict [inspect oo::object]
isa                      = object class
class methods            = destroy
class methods -private   = unknown eval varname variable destroy <cloned>
class methods -all       = destroy
object class             = ::oo::class
object methods -all      = create destroy new
object namespace         = ::oo::Obj1
object commands          = my
object commands -private = my
object commands -all     = my
% pdict [inspect oo::class]
isa                      = object class metaclass
class superclasses       = ::oo::object
class methods            = create new
class methods -private   = create createWithNamespace new
class methods -all       = create destroy new
object class             = ::oo::class
object methods -all      = create destroy
object namespace         = ::oo::Obj2
object commands          = my
object commands -private = my
object commands -all     = my

aspect has dreams of this one day growing into a Smalltalk-esque Object Browser, but this is pretty good from a command line.

EMJ 2016-03-17: and which "map" function are you using here?

Eugene 2016 Apr 14: Just stumbled upon this page today. As I've been working for a while on some kind of Object Browser GUI, I thought it would be nice to share. So, here 's the link to the project page at ChiselApp, and here's a screenshot:

https://lh3.googleusercontent.com/cGN3xqIPWx7oXV2Iq3SklXqNqmhumCtBV8fJgGdX35sTD8RlWeO_YJTvu4iQFZxscD9BpFIzR4WiVPvuU9VI2mmnM0q_2jMeB7wdwhN_OUPrmWWuckbtaor0pr_7wNL_44Fk98VkwzEt0Q7xzfHfKWsBMNIblkrnNaaa51rk18ElpPHfndvOLshphrqHLWrEbPktSQlk3xpRLLjB5pHWoJIwa3QjThz7MAtBFZIP5RAP8IbkQisN5k_vcWMlvaTuByFfUuz7Es97s13JQi6IBFpB9qZwceafdkEcbAHPaoklEhI2OIRmG3wU2DbQvb4fMur7-Wg8D3FfkBwomqToAHsarSDEN2xhAjK2_yTfo7u9ipYjlWxQYazgfTBu9To34nI7lB4UW7ozz6TSGgPZqCjJF7xx98iMp8TV1B-jHgxn8cbMSn91LnnRuZGZIdw2RQnCk5Mra6pYKVpRnQ-sguzQZlaQD9N_vcTBBKUTw1YFJU_Gl3Mkz8z5rzyMsPKTBB5qf3CX5hRxDVY15HWWynwWrrzsGbo8pcgN81s2oybVZ9T9GFdJ8qu3bfOa9Nyq6-o=w698-h444-no?.jpg