tomdoc
tomdoc copied to clipboard
Add direct support for option hashes
A lot of Ruby methods use options hashes as the primary way to pass arguments. Having an easy and intuitive way to document these is extremely important if TomDoc is to be usable, at least for me. I think the current way to do it is verbose and complicated:
# options - The Hash options used to refine the selection (default: {}):
# :color - The String color to restrict by (optional).
# :weight - The Float weight to restrict by. The weight should
# be specified in grams (optional).
How about:
# Options
#
# :count - The Integer number of times to duplicate the text (default: 1).
# :account - The Account used for bamboodling (optional).
# :user - The User responsible that has to answer to the RIAA.
An automated parser could then look for the last argument in the argument list, possibly requiring that its default value be an empty hash:
def copy(source, target, options = {})
...
end
If the name of the options argument should be specified, as it currently does, I suggest adding it in parentheses after the "Options" heading, i.e.:
# Options (opts)
Furthermore, if the options hash itself should be described in depth, I suggest adding a paragraph after the "Options" heading, but before the list of options:
# Options (conditions)
#
# The conditions required for a match.
#
# :active - a Boolean indicating whether only active users should
# match (default: false).
# ...
Update: I've added colons before the option names to indicate that they're symbols. Update 2: Added a suggestion for how to add more context to the options documentation.
I suggested something like this in #17.
Also, note that this is going to need address for Ruby 2.0 b/c keyword arguments are coming.
@trans: regarding Ruby 2, the proposed syntax should be flexible enough to cover those cases. Regarding #17 - it seems to me that @mojombo's argument against that syntax was that it was based too much on convention. In the syntax I am proposing, the author must add a dedicated section covering the options. There doesn't need to be any relation to an actual argument name, as the semantic would simply be "passing in a hash as the last argument". Since methods that accept variable arguments can still have options hashes, this seems better to me, i.e.
# Public: Find one or more Article objects by their id's.
#
# ids - one or more Integer representing the id of an Article.
#
# Options
#
# :published - a Boolean indicating whether only published articles
# should be returned (default: true).
# :limit - an Integer representing the upper limit on the number
# of articles returned, or nil if there should be no
# limit (default: nil).
#
# Returns one or more Article objects.
def find(*ids)
...
end
Note: based on Mr. @mojombo's feedback to #17, I'm changing my proposition to use the full symbol syntax when displaying symbol keys. This should allow more flexibility.
"There doesn't need to be any relation to an actual argument name"
Yes, that was my intent too. Mine really differs only in that the "Options" section header would not be needed. But I'm indifferent to that.
Btw, is it allowable to indent the parameters at all?
# Public: Find one or more Article objects by their id's.
#
# ids - one or more Integer representing the id of an Article.
#
# Options
#
# :published - a Boolean indicating whether only published articles
# should be returned (default: true).
# :limit - an Integer representing the upper limit on the number
# of articles returned, or nil if there should be no
# limit (default: nil).
#
# Returns one or more Article objects.
def find(*ids)
...
end
It's not allowed in the current specification (http://tomdoc.org/), and I'd rather not change that.
I have mixed feelings about it really. Obviously without the indention things are bit more concise, but I also think it is bit less readable.
@trans: that's really an issue for, well, another issue.
true enough. I'll post it as such.
@mojombo BUMP
Hmm, I don't fee like this is any less complex than the current syntax, and to me feels like more syntax you have to remember and more complexity for an automated tool to deal with. Do you really feel like it's that onerous to do the indenting the current way? I've never felt oppressed by it.
It's mainly due to line length considerations - I try to keep lines below 80 chars, but it can be difficult when there's a method with both a long argument name and an options hash, eg.
# Makes the gnome dance.
#
# number_of_gnome_dances - The Integer number of dances the gnome should
# perform.
# options - A Hash of options for the dance:
# :wiggle - A Boolean indicating whether the
# gnome should wiggle.
# :bow_on_finish - A Boolean indicating whether the
# gnome should bow when finished
# dancing.
In an editor or a terminal, horizontal space is a limited resource, not least due to legibility issues. It may just be because I use options hashes extensively. Especially when a method only accepts options does the extra level of indirection feel annoying.
I'm raising this issue because I'd like to see some sort of tool support for a more direct syntax. Perhaps both could be supported, and people could choose what suits them best, maybe on a method-by-method basis?