Inheritance data

2 views
Skip to first unread message

James Coglan

unread,
Nov 18, 2008, 10:02:27 AM11/18/08
to PDoc
Hi list,

I’m doing some stuff related to inheritance information on this
branch:

http://github.com/jcoglan/pdoc/commits/inheritance

Not sure I’m calling it ‘finished’ at any point, but feel free to pull
what you like. I’m trying to figure out how much inheritance
information to assume, given that much of the inheritance semantics is
not baked into JavaScript, it’s defined by the developer. This is
especially true in my JS.Class project (http://jsclass.jcoglan.com),
where class methods are inherited, etc.

One thing we should be able to do is distinguish mixins from
extensions, i.e.

Object.extend(Array.prototype, Enumerable); // mixin
Object.extend(Array, SomeClassMethods); // extension

Currently, ‘includes’ seems to cover both these cases, giving
misleading advice about which object methods are added to (the class,
or its prototype). I really want this so I can document JS.Class
properly, but obviously do not want to hard-code its inheritance
semantics into PDoc. Maybe a couple new tags would fix this?

Tobie Langel

unread,
Nov 20, 2008, 11:10:55 PM11/20/08
to PDoc
I understand your problem pretty well. What do you suggest we do ?

James Coglan

unread,
Dec 1, 2008, 9:49:55 AM12/1/08
to PDoc


On Nov 21, 4:10 am, Tobie Langel <tobie.lan...@gmail.com> wrote:
> I understand your problem pretty well. What do you suggest we do ?


Been thinking about this for a while, sorry for the delay. The only
inheritance system baked into JS is prototypal object-to-object
delegation; there's no such thing as class vs instance methods out of
the box. There's just objects and functions, and we bring various
conventions from other languages. Prototype and PDoc have a Ruby-ish
bent but that doesn't mean it's totally Ruby-like: e.g. in JS.Class,
class methods are inherited whereas in Prototype they aren't (I
think).

One solution might be to allow a tag where you explicitly list the
direct parents of a class. e.g. to say a class inherits from Parent,
getting its class and instance methods, and uses the mixin Observable
(only instance methods):

/**
* class Child < Parent
* includes: Observable
* inherits: Parent#, Parent., Observable#
**/

With classes and modules we basically have two 'namespaces': the
constructor (to which class methods are added) and the prototype where
instance methods live. The above syntax would require you to use a '#'
or '.' to disambiguate a class name. We'd need sensible behaviour when
you omit the trailing sign as well, e.g. assume it's a namespace or
that you're only inheriting instance methods.

I think this would work for mixins too, both in Prototype (where a
mixin is a single namespace) and in JS.Class (which has proper Ruby-
like modules that can have instance and singleton methods). Writing
"Observable#" would match the methods in that module in either case,
as for Prototype you're using the '#' sign for mixin methods. When
listing superclasses and mixins, you'd recurse over each class'
"inherits" list to find all the inherited methods, not just ones from
mixins.

As a starting point, I'd suggest these rules for inheritance:

* Assume instance methods are inherited from the superclass (baked-in
JS behaviour)
* Assume instance methods are inherited from mixins (common pattern,
easy to implement in JS)
* Require that other inheritance namespaces be explicitly mentioned
with the "inherits" tag
* Build a tree from this data and list all inherited methods on doc
pages.
* Differentiate between class and instance methods in method lists.

This is really the first vaguely workable thing that occurred to me,
so do chime in if you can see a better way of doing this.
Reply all
Reply to author
Forward
0 new messages