\documentclass[]{article}
\usepackage{amsmath,graphicx,supertabular,hyperref,tabularx,ifthen}
\title{TIP \#117: Object Type Introspection}
\date{November 01, 2002}
\author{Peter Spjuth}
\urlstyle{sf}
\setlength{\parskip}{1ex}
\setlength{\parindent}{0pt}
\def\tipversion$#1${\texttt{\$#1\$}}
\def\tiplangle#1{\ensuremath{<}}
\def\tiprangle#1{\ensuremath{>}}
\def\tipbar#1{\ensuremath{|}}
\def\tipmail#1#2{\(\langle\){\small\expandafter\url{#1@#2}}\(\rangle\)}
\ifx\pdfoutput\undefined
\newcommand{\tipimage}[2]{\typeout{Make sure you download #1.eps}\ifthenelse{\lengthtest{0.8\textwidth>#2}\and\lengthtest{0pt<#2}}{\includegraphics{#1.eps}}{\includegraphics[width=0.8\textwidth]{#1.eps}}}
\newcommand{\tipxref}[1]{}
\newcommand{\tipxrefend}{}
\else
\newcommand{\tipimage}[2]{\typeout{Make sure you create #1.pdf}\ifthenelse{\lengthtest{0.8\textwidth>#2}\and\lengthtest{0pt<#2}}{\includegraphics{#1.pdf}}{\includegraphics[width=0.8\textwidth]{#1.pdf}}}
\pdfcatalog{/PageMode /UseOutlines}
\newcommand{\tipxref}[1]{\pdfannotlink attr {/C [0.5 0.5 1.0] /Border [0 0 1]} goto name {#1}}
\newcommand{\tipxrefend}{\pdfendlink}
\fi
\newenvironment{tipabstract}{\begin{abstract}}{\end{abstract}}
\begin{document}\maketitle
\begin{center}\begin{tabularx}{\linewidth}{|r@{: }X|}\hline
\textbf{TIP \#117}&\textbf{Object Type Introspection}\\\hline
Author&

Peter Spjuth \tipmail{peter.spjuth}{space.se}
\\
Created&Friday, \(\text{1}^{\text{st}}\) November 2002\\
Type&Project\\
Tcl Version&\(8.5\)\\
State&Withdrawn\\
Vote&Pending\\
Version&\tipversion$Revision: 1.9 $\\
Post History&\\
Obsoleted By&214\\
\hline\end{tabularx}\end{center}
\thispagestyle{empty}\pagestyle{empty}
\begin{tipabstract}

This TIP proposes to add a command to give information on the current internal representation of an object.
\end{tipabstract}
\tableofcontents\setcounter{page}{0}\clearpage\pagestyle{plain}

\section{Rationale}

When trying to understand the internals of objects and when trying to track down shimmering problems it is very helpful to be able to see what type an object currently has.

\section{Specification}

A new package called ``Debug'' is created as part of the core.

A new command, \textit{objtype}, is added to the Debug package. The command has the syntax:

\begin{quote}
\textbf{Debug::objtype} ?\textit{value}?
\end{quote}

If no value is submitted, a list of all currently registered object types are returned.

If a value is submitted, it returns a list where the first element is the name of value's object type, or ``none'' if there is no internal representation. The second element is a boolean stating if the object has a valid string representation.

Examples:
\begingroup\small\begin{verbatim}
% Debug::objtype
boolean index double end-offset wideInt list cmdName bytecode
nsName procbody bytearray int {array search} string
% set apa hejsan
hejsan
% Debug::objtype $apa
none 1
% string length $apa
6
% Debug::objtype $apa
string 1
% regexp $apa hoppsan
0
% Debug::objtype $apa
regexp 1
% Debug::objtype [expr 1+1]
int 0
\end{verbatim}
\endgroup

\section{Discussion}

The first proposal was to add this as a subcommand to info. This was considered bad since this should be a pure debug command and should never be used in live code. Thus the proposition came up to create a Debug package and put it in there to emphasise its debug nature. The Debug package can also be extended in the future with other utilities.

\section{Reference Implementation}
\begingroup\small\begin{verbatim}
static int
ObjTypeCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;	/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    Tcl_Obj *listPtr;

    if ((objc != 2) && (objc != 3)) {
        Tcl_WrongNumArgs(interp, 2, objv, "?value?");
        return TCL_ERROR;
    }

    listPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);

    if (objc == 2) {
        Tcl_AppendAllObjTypes(interp, listPtr);
    } else {
        Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj(
                (objv[2]->typePtr != NULL) ? objv[2]->typePtr->name : "none", -1));
        Tcl_ListObjAppendElement(interp, listPtr,
                Tcl_NewBooleanObj(objv[2]->bytes != NULL));
    }
    Tcl_SetObjResult(interp, listPtr);
    return TCL_OK;
}
\end{verbatim}
\endgroup

\section{Future possibilities}

For further object introspection the command can easily be extended by options.

\section{Copyright}

This document has been placed in the public domain.

\section{Colophon}

\textit{TIP AutoGenerator --- written by Donal K. Fellows}
\end{document}
