spacer spacer spacer

2005-06-02

What is the type of a prototype?

I’m trying to beef up the Laszlo debugger to help myself with the SOLO data reimplementation. I have gotten confused a couple of times because the debugger isn’t careful enough.

The goal of the Debug.__String routine (which is used by Debug.write and Debug.inspect to present objects), is to compactly and unambiguously display objects. For primitive types, it displays a representation that, if evaluated, would give you back an === object. (In Lisp this is called print/read consistency). It can’t do that for objects without giving up its compact goal. So, for instances of Object, what it displays is:

type # uid ( length ) | name

The double-angle-quotes are just there to be distinguish this representation from primitive types (In Lisp, there is a reserved reader macro #< that is used to distinguish ‘unreadable’ objects).

type is meant to be the most specific class where object instanceof class is true.

uid is a unique id assigned by the debugger to distinguish objects whose representation is otherwise the same (e.g., 2 empty objects)

length will be displayed if the object has a property length with a numeric value. This is mostly for arrays, but means that objects that are used as arrays will be displayed usefully too.

name is meant to be some informative information about the object. Users can define a _dbg_name method on their classes to provide this. For LzNode, name will be either '#' + this.id or '.' + this.name. If an object has a toString method, other than the default one, that will be used. Otherwise an abbreviated listing of the objects properties will be used.

Here’s my plan:

  • Verify that type is correct.

    The constructor property of an object should be its type. If that is not the case the type will be annotated '(' + type + '?)', to indicate that something is fishy about this object. This will address the case where an object was showing up as being an object in the old debugger, but it had a null __proto__ and hence compared === null, mystifying more than one of us.

  • Verify that the __proto__ property of the object is normal.

    Normally the __proto__ property of an object should be === the object’s constructor’s prototype. If this is not the case, the object can have non-standard behavior. If the __proto__ is not as expected, the debugger will add a second uid that is the uid of the non-standard prototype object (which can be inspected by using Debug.inspect with Debug.showInternalProperties = true). This will address the case where the __proto__ chain is being (ab)used to implement defaults in parameter lists, for instance.

My question is:

What is the type of a prototype? For a class foo, foo.prototype.constructor === foo, but foo.prototype.__proto__ === Object.prototype (typically, it can be some other classes prototype if the class extends another class). Under my plan, a prototype will always show up as having a broken type. Technically this is correct, because the prototype of a class is not an instance of the class, but I don’t want the user to think all prototypes are broken. What would be the most useful thing to display for the type of a prototype? The class of its __proto__ is what I am thinking.

Post a comment

Thanks for signing in, . Now you can comment. (sign out)

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)


Remember me?


You are not signed in. You need to be registered to comment on this site. Sign in