How to document a function inside a function?

1,433 views
Skip to first unread message

Kruncher

unread,
Aug 27, 2011, 9:51:28 PM8/27/11
to JSDoc Users
How can jsdoc be used to document the following?

`foo` is both a namespace and a function (it isn't a class!)

/**
* Foo...
* @param {number} a first argument
* @param {number} b second argument
*/
foo = function(a, b) {
};

/**
* Bar...
* @param {number} a first argument
*/
foo.bar = function(a) {
};

/**
* Baz...
* @param {number} a first argument
* @param {number} b second argument
*/
foo.baz = function(a, b) {
};

Lea Hayes

unread,
Aug 28, 2011, 7:57:02 PM8/28/11
to JSDoc Users
The following kind of works, but it doesn't seem semantically correct:

/**
* Bar...
* @function foo,bar
* @param {number} a first argument
*/
foo.bar = function(a) {

};


Michael Mathews

unread,
Aug 29, 2011, 1:55:17 AM8/29/11
to Kruncher, JSDoc Users
Hi Lea,

The goal is to make documenting the easy stuff easy and the hard stuff possible. Your example falls into the hard category for documentation. What makes it hard is that by the time we document "bar" there are two containers named "foo" that it could be documented under. Imagine the `@memberof foo` tag were explicitly added to the doc comment for bar (in reality it is implicitly added for you by JSDoc). It is ambiguous which of the two foos that bar belongs to. [Note that this same problem would appear again if you were to `@see foo` or {@link foo} -- there needs to be some way to tell the two foos apart.]

There is a mechanism for resolving this, but it means you will have to be explicit in every doc comment you write. For example, in JSDoc 3, you would name one of the foos like so: "foo(1)", while the other would be "foo(2)". Then, when it comes time to document bar, you must say @memberof foo(1) or @memberof foo(2).

// in JSDoc 3...
/**
* Describe the namespace.
* @namespace foo(1)
*/

/**
* Describe the function.
* @function foo(2)


* @param {number} a first argument
* @param {number} b second argument
*/
foo = function(a, b) {
};

/**
* Bar...
* @function bar
* @memberof foo(1)


* @param {number} a first argument
*/
foo.bar = function(a) {
};

/**
* Baz...
* @function baz
* @memberof foo(1)


* @param {number} a first argument
* @param {number} b second argument
*/
foo.baz = function(a, b) {
};

The syntax is slightly different in JSDoc Toolkit, but in *either* case you could make things easier by leaving the name of the more common foo as it was, for example, if you mention the namespace foo a lot in your docs, while the function foo is only mentioned once, it would make sense to document the namespace as "foo" and the function "foo(1)" or "foo^1". Here's how you would document that in JSDoc Toolkit.

// in JSDoc Toolkit
/**
* Describe the namespace.
* @namespace
* @name foo
*/

/**
* Describe the function.
* @function
* @name foo^2


* @param {number} a first argument
* @param {number} b second argument
*/
foo = function(a, b) {
};

/**
* Bar...
* @function
* @name bar
* @memberof foo


* @param {number} a first argument
*/
foo.bar = function(a) {
};

/**
* Baz...
* @function
* @name baz
* @memberof foo


* @param {number} a first argument
* @param {number} b second argument
*/
foo.baz = function(a, b) {
};

Note that there is a related but different problem where you may like to have more than one doc comment for a single piece of code, for example if you wanted to document a single function as both a setter and then again as a getter. In that case it's only one function not two and so there is a different solution to documenting it.

Michael Mathews
mic...@gmail.com

> --
> You received this message because you are subscribed to the Google Groups "JSDoc Users" group.
> To post to this group, send email to jsdoc...@googlegroups.com.
> To unsubscribe from this group, send email to jsdoc-users...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/jsdoc-users?hl=en.
>

Lea Hayes

unread,
Aug 29, 2011, 6:36:48 PM8/29/11
to JSDoc Users
Hello Michael

Thank you for the detailed response. That makes a lot of sense, I also
agree completely with your very first sentence.

> Note that there is a related but different problem where you may like to have more than one doc comment for a single piece of code, for example if you wanted to document a single function as both a setter and then again as a getter. In that case it's only one function not two and so there is a different solution to documenting it.

Do you feel that it is beneficial to document dual purpose setter/
getter functions separately?

Thanks again!
> micm...@gmail.com

Michael Mathews

unread,
Aug 29, 2011, 7:11:24 PM8/29/11
to Lea Hayes, JSDoc Users

Michael Mathews
mic...@gmail.com

On 29 Aug 2011, at 23:36, Lea Hayes wrote:

> Hello Michael
>
> Thank you for the detailed response. That makes a lot of sense, I also
> agree completely with your very first sentence.
>
>> Note that there is a related but different problem where you may like to have more than one doc comment for a single piece of code, for example if you wanted to document a single function as both a setter and then again as a getter. In that case it's only one function not two and so there is a different solution to documenting it.
>
> Do you feel that it is beneficial to document dual purpose setter/
> getter functions separately?

That's a good question. From a documentation point-of-view it is always easier to have one API for one action. For example you could have `setVal(v)` and `getVal()` methods instead of a combined version named just "val". Having the two separate methods is more efficient at runtime too, since there isn't any requirement for the combined function to determine if it is setting or getting on every call, as the user has already codified that decision at write-time by choosing to call either set or get.

Having said that, it does seem to be popular to overload single methods with lots different APIs depending on the arguments given {@see jQuery}. There isn't any official way to support that in JSDoc 2, but it was a goal of mine in JSDoc 3 to make it possible to have multiple doc comments attached to a single method if that is what the developer wanted. This feature is called "@also" internally, but the simplest way to use it is to just stack multiple doc comments up, one immediately after another, like so:

https://github.com/micmath/jsdoc/blob/master/test/cases/also.js

/** @class */
function Asset() {
this._name = '';
}

/**
*
* Set the value of the name property.
* @param {string} newName
*
*//**
*
* Get the value of the name property.
* @returns {string}
*
*/
Asset.prototype.name = function(newName) {
if (newName) { this._name = newName; }
else { return this._name; }

Lea Hayes

unread,
Aug 29, 2011, 7:23:00 PM8/29/11
to JSDoc Users
That is a really neat feature! easy to understand as a comment and
renders beautifully.

I had a go (because I just had to :P) at stacking three variants and
it just works so well. There are often scenarios where a function has
various signatures that make documentation impossible. I had a similar
problem in a PHP project that I am working on and I ended up having to
restructure my code just so that I could add sensible docblocks.

I would love to see the same notation in phpdoc!


On Aug 30, 12:11 am, Michael Mathews <micm...@gmail.com> wrote:
> Michael Mathews
> micm...@gmail.com
Reply all
Reply to author
Forward
0 new messages