Code Documentation
Code Documentation
Mongoid uses its own flavor of YARD for code documentation. Please note the conventions outlined in this document.
Structure
Modules: All class and module definitions should be preceded by a documentation comment.
# This is the documentation for the class. It's amazing # what they do with corrugated cardboard these days. class CardboardBox Methods: All method definitions should be preceded by a documentation comment. Use
@param
,@yield
, and@return
to specify inputs and output. For further details, refer to Type Declaration below.# Turn a person into whatever they'd like to be. # # @param [ Person ] person The human to transmogrify. # # @return [ Tiger ] The transmogrified result. def transmogrify(person) Errors: Use
@raise
to explain errors specific to the method.# @raise [ Errors::Validations ] If validation failed. def validate! Private Methods: Private methods should be documented unless they are so brief and straightforward that it is obvious what they do. Note that, for example, a method may be brief and straightforward but the type of its parameter may not be obvious, in which case the parameter must be appropriately documented.
private # Documentation is optional here. def do_something_obvious API Private: Classes and public methods which are not intended for external usage should be marked
@api private
. This macro does not require a comment.Note that, because Mongoid's modules are mixed into application classes,
private
visibility of a method does not necessarily indicate its status as an API private method.# This is an internal-only method. # # @api private def dont_call_me_from_outside Notes and TODOs: Use
@note
to explain caveats, edge cases, and behavior which may surprise users. Use@todo
to record follow-ups and suggestions for future improvement.# Clear all stored data. # # @note This operation deletes data in the database. # @todo Refactor this method for performance. def erase_data! Deprecation: Use the
@deprecated
macro to indicate deprecated functionality. This macro does not require a comment.# This is how we did things back in the day. # # @deprecated def the_old_way
Formatting
Line Wrapping: Use double-space indent when wrapping lines of macros. Do not indent line wraps in the description.
# This is the description of the method. Line wraps in the description # should not be indented. # # @return [ Symbol ] For macros, wraps must be double-space indented # on the second, third, etc. lines. Whitespace: Do not use leading/trailing empty comment lines, or more than one consecutive empty comment line.
# GOOD: # @return [ Symbol ] The return value def my_method # BAD: # @return [ Symbol ] The return value # def my_method # BAD: # @param [ Symbol ] foo The input value # # # @return [ Symbol ] The return value def my_method(foo)
Type Declaration
Type Unions: Use pipe
|
to denote a union of allowed types.# @param [ Symbol | String ] name Either a Symbol or a String. Nested Types: Use angle brackets
< >
to denote type nesting.# @param [ Array<Symbol> ] array An Array of symbols. Hash: Use comma
,
to denote the key and value types.# @param [ Hash<Symbol, Integer> ] hash A Hash whose keys are Symbols, # and whose values are Integers. Array: Use pipe
|
to denote a union of allowed types.# @param [ Array<Symbol | String> ] array An Array whose members must # be either Symbols or Strings. Array: Use comma
,
to denote the types of each position in a tuple.# @return [ Array<Symbol, Integer, Integer> ] A 3-member Array whose first # element is a Symbol, and whose second and third elements are Integers. Array: Use pipe
|
on the top level if the inner types cannot be mixed within the Array.# @param [ Array<Symbol> | Array<Hash> ] array An Array containing only # Symbols, or an Array containing only Hashes. The Array may not contain # a mix of Symbols and Hashes. Nested Types: For clarity, use square brackets
[ ]
to denote nested unions when commas are also used.# @param [ Hash<Symbol, [ true | false ]> ] hash A Hash whose keys are Symbols, # and whose values are boolean values. Ruby Values: Specific values may be denoted in the type using Ruby syntax.
# @param [ :before | :after ] timing One of the Symbol values :before or :after. True, False, and Nil: Use
true
,false
, andnil
rather thanTrueClass
,FalseClass
, andNilClass
. Do not useBoolean
as a type since it does not exist in Ruby.# GOOD: # @param [ true | false | nil ] bool A boolean or nil value. # BAD: # @param [ TrueClass | FalseClass | NilClass ] bool A boolean or nil value. # @param [ Boolean ] bool A boolean value. Return Self: Specify return value
self
where a method returnsself
.# @return [ self ] Returns the object itself. Splat Args: Use three-dot ellipses
...
in the type declaration and star*
in the parameter name to denote a splat.# @param [ String... ] *items The list of items name(s) as Strings. def buy_groceries(*items) Splat Args: Do not use
Array
as the type unless each arg is actually an Array.# BAD: # @param [ Array<String> ] *items The list of items name(s) as Strings. def buy_groceries(*items) buy_groceries("Cheese", "Crackers", "Wine") # OK: # @param [ Array<String>... ] *arrays One or more arrays containing name parts. def set_people_names(*arrays) set_people_names(["Harlan", "Sanders"], ["Jane", "K", ""Doe"], ["Jim", "Beam"]) Splat Args: Use comma
,
to denote positionality in a splat.# @param [ Symbol..., Hash ] *args A list of names, followed by a hash # as the optional last arg. def say_hello(*args) Splat Args: Specify type unions with square brackets
[ ]
.# @param [ [ String | Symbol ]... ] *fields A splat of mixed Symbols and Strings. Keyword Arguments: Following YARD conventions, use
@param
for keyword arguments, and specify keyword argument names as symbols.# @param [ String ] query The search string # @param [ Boolean ] :exact_match Whether to do an exact match # @param [ Integer ] :results_per_page Number of results def search(query, exact_match: false, results_per_page: 10) Hash Options: Define hash key-value options with
@option
macro immediately following the Hash@param
. Note@option
parameter names are symbols.# @param opts [ Hash<Symbol, Object> ] The optional hash argument(s). # @option opts [ String | Array<String> ] :items The items(s) as Strings to include. # @option opts [ Integer ] :limit An Integer denoting the limit. def buy_groceries(opts = {}) Double Splats: Use double-star
**
in the parameter name to denote a keyword arg splat (double splat). Note that type does not need declared on the double-splat element, as it is implicitly <Symbol, Object>. Instead, define value types with@option
macro below. Note@option
parameter names are symbols.# @param **kwargs The optional keyword argument(s). # @option **kwargs [ String | Array<String> ] :items The items(s) as Strings to include. # @option **kwargs [ Integer ] :limit An Integer denoting the limit. def buy_groceries(**kwargs) Blocks: Use
@yield
to specify when the method yields to a block.# @yield [ Symbol, Symbol, Symbol ] Evaluate the guess of who did the crime. # Must take the person, location, and weapon used. Must return true or false. def whodunit yield(:mustard, :ballroom, :candlestick) end Blocks: If the method explicitly specifies a block argument, specify the block argument using
@param
preceded by an ampersand&
, and also specify@yield
. Note@yield
should be used even when method callsblock.call
rather thanyield
internally.# @param &block The block. # @yield [ Symbol, Symbol, Symbol ] Evaluate the guess of who did the crime. # Must take the person, location, and weapon used. Must return true or false. def whodunit(&block) yield(:scarlet, :library, :rope) end # @param &block The block. # @yield [ Symbol, Symbol, Symbol ] Evaluate the guess of who did the crime. # Must take the person, location, and weapon used. Must return true or false. def whodunit(&block) block.call(:plum, :kitchen, :pipe) end Blocks: Use
@yieldparam
and@yieldreturn
instead of@yield
where beneficial for clarity.# @param &block The block. # @yieldparam [ Symbol ] The person. # @yieldparam [ Symbol ] The location. # @yieldparam [ Symbol ] The weapon used. # @yieldreturn [ true | false ] Whether the guess is correct. def whodunit(&block) yield(:peacock, :conservatory, :wrench) end Proc Args: Proc arguments should use
@param
(not@yield
). The inputs to the proc may be specified as subtype(s).# @param [ Proc<Integer, Integer, Integer> ] my_proc Proc argument which must # take 3 integers and must return true or false whether the guess is valid. def guess_three(my_proc) my_proc.call(42, 7, 88) end