Objects as parameters

6 views
Skip to first unread message

mvanleeu

unread,
Dec 11, 2007, 10:40:38 AM12/11/07
to jgrousedoc
Hi,

Many libraries, as does the one I want to document, uses an object as
unique parameter to a function/constructor. How can I write the doc
for such a case? For example

function foo(o) {
...
}
...
foo({
param1: 'hello',
param3: 'world
});

NB: Please note that attribute 'param2' was in fact optional (I want
the documentation to specify that) and was thus omitted in my example.

I look for something similar to @config {type} propertyname in jsdoc-
toolkit (and I would like to indicate when a property is optional)

Regards,

Mark

denis.r...@gmail.com

unread,
Dec 11, 2007, 6:59:55 PM12/11/07
to jgrousedoc
One of the ways to do something like that:

/**
@interface MyComplexParam
*/
/**
@variable param1
*/
/**
@variable param2 - optional
*/

/**
@variable param3
*/

...... switch of the context
/**
@function foo
@param {MyComplexParam} o
*/

I understand that this is not necessarily 100% exactly what you were
expecting, but should be a decent approximation.
Currently the "optional" modifier could be applied to parameters only,
but I think that we've got a decent case that would justify usage of
it for other cases, like variables/properties/etc

I am quite open to suggestions, so if you think that jGrouseDoc would
benefit from additional tags, feel free to suggest the syntax and
expected behavior.

Regards,
Denis

mvanleeu

unread,
Dec 12, 2007, 6:48:02 AM12/12/07
to jgrousedoc
The way you proposed is actually close to what I am using right now
(I'm using @object with @variable) BUT:
- It introduces some additional (more less) public interfaces that
appear as top level elements.
- interfaces is not a concept a Javascript developer is supposed to
know, but I am aware that jGrouse is specifically "javascript"
oriented ;-)
- It does not fully allow to define the concept I described in my
example, which is fairly common in Javascript lately.

I will think of a sensible suggestion regarding a syntax for such
cases and come back to you in this thread when I have
something...realistic :-)

Mark

Broofa

unread,
Dec 12, 2007, 7:57:45 AM12/12/07
to jgrousedoc
Yeah, something like that had occured to me to (although I would have
used @structure, not @interface). But... well... *YUCK!* :-) We're
trying to document an function parameter here, not an entire
interface.

... well, actually, technically it is an interface but the end-user
need is for a much more compact and ad-hoc method of defining the
interface inline, as part of the function comment as a whole.

I took a look at @config and, for the cases it addresses, it's much
more usable than the jGD counterpart. The problem is that its
(@config's) utility is pretty limited. It only allows you to
document simple name-type pairs. You can't specify a return type (if
you're trying to document a function), and you can't specify any sort
of signature if the property in question is a function (e.g. if param1
needs to point to a {String} function(int, int) or something like
that).

Granted, those cases are not as common - and certainly having an
@config-type option available would be nice, but it would be even
better if you could leverage existing tags to describe argument
parameters in the same way you describe objects and functions
normally.

We touched on this subject a while back in this thread:
http://groups.google.com/group/jgrousedoc/browse_thread/thread/4e2e4079655dc802/dd76cdfd79a24d1e?hl=en&lnk=gst&q=%40sig#dd76cdfd79a24d1e
Although at the time we were just thinking about how to document the
signatures of passed functions (and events), and not objects in
general.

By way of a suggestion, here's one possibility, which I'm sure would
be a parsing nightmare, but what the heck: Support nested interface
declarations inside the type brackets ({}). Mark's example might look
something like this:

/**
* @function myObject
* @param {@object
* @var {String} param1 comment_for_var
* @var {String} param3 comment_for_var
* } param_name comment_for_param
*/

... and a passed-function might look like this:

/**
* @function myFunction
* @param {@function
* @param {String} param1 comment_for_param
* @param {int} param2 comment_for_param
* @return comment_for_return
* } callback Comment for a function with an in-line interface
definition
*/

... and putting the two together for an example of how myFunction
could nest inside myObject:

/**
* @function myFunction
* @param {@object
* @var {String} param1 comment_for_var
* @var {@function
* @param {String} param1 comment_for_param
* @param {int} param2 comment_for_param
* @return comment_for_return
* } callback Comment for a function with an in-line interface
definition
* @var {String} param3 comment_for_var
* } param_name comment_for_param
*/

That last example gets a bit ugly, but is actually not too bad if you
consider the complexity of what it's expressing.

This would solve(?) half of the problem - how to author such ad-hoc
interfaces in the comments. The other half of the problem - how you
render such information in the generated docs - would still need to be
addressed.

denis.r...@gmail.com

unread,
Dec 13, 2007, 7:07:14 AM12/13/07
to jgrousedoc
Hmmm

That sounds more like an overkill to me.

I would say, it is quite reasonable to expect that if you have a
function-parameter or function-return type then you should have a
corresponding @ifuction tag to describe the signature of that
function. Hence the problem is simply reduced to usage of @config (or
whatever we choose to call it)

In this case the description for Mark's example would be reduced to:

/**
bla-bla-bla
@function {returnType} myFunction
@param myParam -- btw, what would be the param type??
@config {String} param1 - default value is 'hello'
@config {optional int} param2
@config {String} param3 - blah blah default is 'World'
....
*/
That would appear quite compact and address 95% of cases. The question
is - Mark's example mentions default values, while this syntax does
not support it. Should it be a concern? Any suggestions?

Also the open question is how to render the documentation, both
summary and detailed sections for such declarations.

Regards,
Denis
On Dec 12, 7:57 am, Broofa <bro...@gmail.com> wrote:
> Yeah, something like that had occured to me to (although I would have
> used @structure, not @interface). But... well... *YUCK!* :-) We're
> trying to document an function parameter here, not an entire
> interface.
>
> ... well, actually, technically it is an interface but the end-user
> need is for a much more compact and ad-hoc method of defining the
> interface inline, as part of the function comment as a whole.
>
> I took a look at @config and, for the cases it addresses, it's much
> more usable than the jGD counterpart. The problem is that its
> (@config's) utility is pretty limited. It only allows you to
> document simple name-type pairs. You can't specify a return type (if
> you're trying to document a function), and you can't specify any sort
> of signature if the property in question is a function (e.g. if param1
> needs to point to a {String} function(int, int) or something like
> that).
>
> Granted, those cases are not as common - and certainly having an
> @config-type option available would be nice, but it would be even
> better if you could leverage existing tags to describe argument
> parameters in the same way you describe objects and functions
> normally.
>
> We touched on this subject a while back in this thread:http://groups.google.com/group/jgrousedoc/browse_thread/thread/4e2e40...

denis.r...@gmail.com

unread,
Dec 15, 2007, 10:07:10 PM12/15/07
to jgrousedoc
I have made a first cut and added support for @paramOption (it is
quite close to previously mentioned @config - I just don't like
@config in this context).

Here is an example of documentation:
/**
handing of SIMPLE_EVENT. Sample link for {@link
listenerCallbackComplex this link}
@ifunction {listenerCallbackComplex} listenerCallbackSimple
@param firstParam describes something
@paramOption {public int} paramOne - for test 1
@paramOption {optional MyObject} paramTwo - for test2
@paramOption {private optional Date} paramThree = {banzai} - for
Test3
@param {String} secondParam yet something else
*/

and rendered output (fancy formatting omitted):

ifunction listenerCallbackSimple

listenerCallbackComplex listenerCallbackSimple(firstParam, String
secondParam)
handing of SIMPLE_EVENT. Sample link for this link
Parameters:
firstParam describes something
{
public int paramOne - for test 1
[MyObject paramTwo] - for test2
[private Date paramThree] = {banzai} - for Test3
}
secondParam yet something else


The code is in svn, feel free to try it.

How do you like it? Suggestions are welcome

Regards,
Denis

Broofa

unread,
Dec 16, 2007, 10:04:01 AM12/16/07
to jgrousedoc
Hey Denis,

I'm not a big fan of the @paramOption name. I think "option" is
confusing in exactly the way "config" is confusing - We (the doc
authors) are not configuring anything or setting any options, we're
extending the definition of @param.

Which has me wondering, "Why not use the usual symbol for continuation
- the ellipses ('...') -as the tag prefix???" Specifically, how would
you feel about replacing @paramOption with these tags instead:
"@...var" - to document object structure parameters
"@...param" - to document parameters of a function parameter
"@...return" - to document return value of a function parameter

I see several benefits to this:
- the "..." prefix is something we all intuitively understand to
indicate a continuation of something.
- the "..." just _looks_ much better. It's visually distinctive and
makes it easy to see wher the parameter definition ends and the next
begins
- the var, param, and return tags will all be familiar to users, so
it's not really like we're introducing a new tag here and have to
explain what it means all over again.

For example:
/**
function {Number} myFunction My function description
@param {Object} param1 This is an object structure
@...var {Number} x Describe the 'x' param
@...var {Number} y Describe the 'y' param
@...var {optional String} text Describe the 'text' param
@param {Function} param2 This is a function parameter
@...param {public int} arg1 For test 1
@...param {optional Object} arg2 For test2
@...return Describe the expected return value
@param {String} param3 Our last param
*/

(See what I mean about '...' being visually distinctive in the
comment!)

As far as output goes, I think it's pretty much what you have,
although I wouldn't use '{}' to delimit the list of parameter
properties - it's a bit confusing when the parameter is a function,
where you'd expect the arguements to be in '()'. Instead, the
parameter properties in a suitably-indented bulleted list. E.g...

function listenerCallbackSimple

Function myFunction(Object param1, Function param2, String param3)
My function description
Parameters:
param1 This is an object structure
o Number x - Descripe the 'x' param
o Number y - Descripe the 'y' param
o [optional String] test Describe the 'text'param
param2 This is a function parameter
o public int arg1 For test 1
o [optional Object] arg2 For test2
o return - Describe the expected return value
param3 Our last param

denis.r...@gmail.com

unread,
Dec 16, 2007, 10:46:13 PM12/16/07
to jgrousedoc
OK, if you prefer bulleted lists it could be easily added instead of
{}

Cannot agree though with the proposal to allow inline declarations of
functions, objects, etc.
Not to mention technical complexities, it would make comments almost
unreadable in the source code.
The situation becomes quite ambiguous when you would have a
"paramOption" (for the lack of better name) that is a function that
has parameter of an object (with specific structure that you might
want to specify), but also the function itself has certain
properties...

No, I firmly believe that it is necessary to draw a line - if you want
to provide detailed description of your parameter-function then use
@ifunction tag.
Or, for trivial cases, you could specify something like
@param {int function(String, Object[, Date=today])} myCallback
(of course, the same could be done in other cases - you can specify
almost arbitrary string in type declaration, as long as it does not
contain '}').

I am not particularly stuck on the name @paramOption, we could use any
other keyword we agree upon. The only restriction is that it must
follow rules for Java/Javascript identifiers/keywords.


On a kind of related note, I have found it quite convenient to provide
an API for my JavaScript libraries that allows calling of functions
either in standard way or in Perl way, by passing an object with
members that are mapped to function arguments.
So if you have a
function blah(a, b, c, d)
it could be called either in a regular way
blah(a,b,c,d)
or in Perl way
blah({a:34, c:'qwerty'})

Regards,
Denis
> ...
>
> read more >>

Broofa

unread,
Dec 17, 2007, 9:33:29 AM12/17/07
to jgrousedoc
I see you're point about drawing the line when it comes to inline
declarations. As long as @ifunction is there as a fallback for the
more complex cases, then restricting the inline options to something
along the lines of your proposal makes sense.

The @paramOption name definitely bothers me. The user is going to be
documenting a param that is either a function or an object, right? It
seems pretty obvious to me that the tags they use to do that should
have at least a passing resemblance to the tags they use when
documenting functions/objects in non-parameter cases. Right? Or am I
missing something here?

Hence, my suggestion in my last post for using a set of tags that
ended in the familiar "param" and "var" terms. If you reread my
proposal, you'll see that I wasn't suggesting the behavior be
different from your paramOption idea - i.e. no elaborate nesting
behavior or anything like that - only that the user be provided a set
of familiar aliases for the functionality you described.

I think "@...var" and "@...param" are easily the best choice for tag
names. They're intuitive and easy to type. And the distinctive
visual indentation they provide is a pretty significant usability
advantage. Thus I'm forced to ask why tag names have to conform to
java/javascript identifier rules? We're not writing java/script after
all. Perhaps a simple pre-processing step to convert "@..." to
"@dotdotdot" as a workaround ...?

mvanleeu

unread,
Dec 17, 2007, 10:12:00 AM12/17/07
to jgrousedoc
Hi Dennis,

I just tested the svn version, no problems so far. A few suggestions:
- The presentation as suggested by Broofa with bullets seems much
better to me (I wouldn't try to mimic an object literal syntax here).
- Maybe we could rename @paramOption to @paramProperty, as (at least
for Javascript) that is exactly what it is, the "property" of the
object used as parameter (as the term "property" is used by ECMA and
for example the well known Oreilly's "Javascript the definitive guide"
book).
- I haven't checked but is the "[foo]" presentation standard
throughout jGrouse for optional parameters?

--
Regards,

Mark

mvanleeu

unread,
Dec 17, 2007, 10:12:34 AM12/17/07
to jgrousedoc

mvanleeu

unread,
Dec 17, 2007, 10:19:27 AM12/17/07
to jgrousedoc


On Dec 17, 4:46 am, denis.riabtc...@gmail.com wrote:

> No, I firmly believe that it is necessary to draw a line - if you want
> to provide detailed description of your parameter-function then use
> @ifunction tag.
> Or, for trivial cases, you could specify something like
> @param {int function(String, Object[, Date=today])} myCallback
> (of course, the same could be done in other cases - you can specify
> almost arbitrary string in type declaration, as long as it does not
> contain '}').

Just a question here. I would I document cases as the bar function
described in the exemple below

function foo(param) where param is an object with the following
attributes:
- gee: a string
- bar: a function accepting two strings and returning a int.

I don't see using ifunction here as it should be a @paramOption (or
any name chose for that "beast")?

--
Regards,

Mark

denis.r...@gmail.com

unread,
Dec 17, 2007, 8:10:17 PM12/17/07
to jgrousedoc
Two options

(both assuming the keyword @paramOption - actual syntax TBD)

The simplest one

/**
@function foo
@param obj
@paramOption {string} gee - first param
@paramOption {int function(string, string)} bar - second
param
*/

Second option, in case if you would want to provide more detailed
description of the function's prototype


/**
Super duper function that does something
@ifunction {int} MyFuncProto
@param {string} str1
@param {string} str2
*/

/**
@function foo
@param obj
@paramOption {string} gee - first param
@paramOption {MyFuncProto} bar - second param

*/

In the second case MyFrontProto would be rendered as a hyperlink to
ifunction's definition

regards,
Denis

denis.r...@gmail.com

unread,
Dec 17, 2007, 8:46:38 PM12/17/07
to jgrousedoc
OK, seems like we're coming to common ground :-)

What i do not agree is the suggestion that allows specification of
var, param, etc
The suggestion gives user an idea that not only var is allowed, but
also function, property, you name it.
We're documenting a simple structure, right? Because anything non-
trivial would reasonably require a separate documentation.
My point is that it must be only one keyword, and at this moment I
don't have a strong preference what it should be (note that we have
effectively ruled out the need for @...param). If it would turn out
that something like @...var would be the choice of majority, then I
would add support for it, although it would require certain tricks.
Mark is suggesting @paramProperty, which also could be an option.

Other suggestions? Votes?

On a related note, Mark, indeed [foo] in rendered documentation
indicates optional parameter. In the published version 1.5 in details
the renderer is adding "(optional)" instead, but in the version that
is currently in svn it is being replaced by [].

Regards,
Denis

Broofa

unread,
Dec 17, 2007, 11:09:39 PM12/17/07
to jgrousedoc
Just to be clear, I wasn't proposing anything other than 'var' and
'param' (I'll retract the @...return suggestion). Those are the two
terms that I think we can all agree are used to document the two use
cases we've been talking about - simple object parameters and simple
function parameters. As I think you said, anything more complex than
that would use @ifunction.

The reason I'm pushing back so hard on this is that users are much
better served by tags that have clear, obvious semantics. And I'm
pretty sure that trying to find a single word that means "object
variable or function parameter" will only lead to some uselessly
abstract name, like "config". We might as well just call it
"@fluffyBunny" and save ourselves the time! :-)

The problem with unclear terms is that when it comes to users, we -
the people in this forum - are the exception. Most other folks -
certainly the other engineers I've convinced to use this tool - don't
have the time to learn all the ins and outs of each tag even if they
have the inclination. Tags are, more often than not, used in an ad-
hoc style based on what people think the tag name means, not what the
tool author says it should mean.

Clear semantics also make it easier to leverage the tagged information
in the future. We may not want to distinguish between params and vars
today, but it'd sure be nice to have that distinction down the road if
we change our minds.

My $.02

denis.r...@gmail.com

unread,
Dec 18, 2007, 7:49:56 AM12/18/07
to jgrousedoc
I am still missing the point of having @param without @return,
especially since we have decided that @ifunction is the way to go.

Hey, why don't we use just "@..." ? If later down the road we would
see that there is a need for distinct "parameter descriptions" then we
would add it as the cases appear. Hope it is a bit better than
@fluffyBunny :-)

Denis

Broofa

unread,
Dec 23, 2007, 10:43:43 AM12/23/07
to jgrousedoc
Hey Denis, I just bumped into a case where I'd like to describe a
returned object using this same technique. E.g. I'm returning the
following object:

{
top: #,
left: #,
width: #,
height: #
}

Any thoughts on how this would be documented? Maybe like so...

* @function {Object} getBounds
* @... {Number} top blahblahblah
* @... {Number} left blahblahblah
* @... {Number} width blahblahblah
* @... {Number} height blahblahblah
* @param firstArgument

Seems like that would work. :)

denis.r...@gmail.com

unread,
Dec 23, 2007, 1:51:23 PM12/23/07
to jgrousedoc
Looks like a legit case

I would modify it a bit though:

* @function {Object} getBounds
* @return structure with the following fields:
* @... {Number} top blahblahblah
* @... {Number} left blahblahblah
* @... {Number} width blahblahblah
* @... {Number} height blahblahblah
* @param firstArgument

And that would also give an idea where the output should be rendered.

(good - seems like we're in an agreement regarding @...)

Regards,
Deins

Broofa

unread,
Dec 23, 2007, 2:20:37 PM12/23/07
to jgrousedoc
Hmm... I guess that makes sense. Explicitly requiring @return is a
bit clearer I guess.
Reply all
Reply to author
Forward
0 new messages