[namespace ensemble] objects - see [NEM]'s [Using namespace ensemble without a namespace] (in fact, it uses ::). [RS] hacked together this little candybox as a variation on that page: namespace eval neo {variable version 0.1} proc neo::new {name _where_ args} { set map [dict create] foreach {slot = value} $args { dict set map $slot $value } namespace ensemble create -command $name -map $map } proc neo::slot {object slot = command args} { set map [namespace ensemble configure $object -map] dict set map $slot [linsert $args 0 $command] namespace ensemble configure $object -map $map } proc neo::method {object name params body} { set params [linsert $params 0 self] slot $object $name = ::apply [list $params $body ::] $object } proc neo::const val { return $val } interp alias {} neo::config {} namespace ensemble configure proc neo::delete name {rename $name {}} #-- So far for neo the "system", the rest is tests and demos: proc rect {canv x0 y0 x1 y1} { set id [$canv create rect $x0 $y0 $x1 $y1] set obj [neo::new $canv.rect$id where \ id = [list const $id] \ coords = [list ::$canv coords $id]] neo::slot $obj canvas = const $canv set obj } catch {destroy .c} ;# good for repeated sourcing pack [canvas .c] set r [rect .c 20 20 100 100] puts "id = [$r id], coords = [$r coords]" neo::slot $r type = const "rectangle" ;#-- object-specific slot puts "$r is a [$r type]" neo::method $r width {} { lassign [$self coords] x0 y0 x1 y1 expr {abs($x1-$x0)} } neo::method $r height {} { lassign [$self coords] x0 y0 x1 y1 expr {abs($y1-$y0)} } puts height:[$r height],width:[$r width] neo::method $r area {} { expr {[$self width] * [$self height]} } puts "area = [$r area]" puts [neo::config $r -map] ---- [Category Object Orientation]