In a Ruby gem documented with YARD, how do you describe a public method's parameters, return value, exceptions and usage with tags?
answer
- @tag lines inside the comment
- [Types] in square brackets
- @param covers keyword arguments too
- @raise [ErrorClass] condition
- @example title, then indented code
basics
~20 sYARD reads @tags from the comment above a method: @param name [Type] for each positional or keyword argument, @return [Type] for the result, @raise [ErrorClass] for exceptions and @example for indented usage code. yard doc renders them as structured HTML.
solid answer
~40 sAbove `def geocode(address, country: nil)` you write a one-line summary, then `@param address [String] ...` and `@param country [String, nil] ...` (keyword arguments use `@param` too; `@option` is only for keys of an options Hash), `@return [GeoLookup::Place, nil] ...`, `@raise [GeoLookup::RateLimitError] ...` and `@example` with an optional title followed by indented code. Types are a free-form list in brackets: `[String, nil]`, `Array<Place>`, `Hash{Symbol => String}`, a duck type like `[#read]`, and the conventional `Boolean`. Methods that yield use `@yield`, `@yieldparam` and `@yieldreturn`; `{GeoLookup::Place}` makes a link. `yard doc` writes HTML to `doc/` and caches the parse in `.yardoc`, and it warns when a `@param` name does not match the signature.
code
ruby · 15 linesmodule GeoLookup
class Client
# Converts coordinates back into an address.
#
# @param lat [Float] latitude in decimal degrees
# @param lng [Float] longitude in decimal degrees
# @yieldparam place [GeoLookup::Place] each candidate, best first
# @return [Array<GeoLookup::Place>] every candidate found
# @raise [ArgumentError] if lat is outside -90..90
# @example Nearest address to a point
# client.reverse(52.5163, 13.3777).first.street
def reverse(lat, lng, &block)
end
end
endgo deeper
Recall the four tags for a public method: @param, @return, @raise and @example, and that the type goes in square brackets.
Explain the type conventions, [String, nil], Array<Place>, Array(Float, Float), duck types, and why keyword arguments take @param while @option is for an options Hash.
Show how tags pay off operationally: YARD warns on unknown @param names after a rename, directives document define_method APIs, and .yardopts keeps every run consistent.
Weigh YARD against plain RDoc for a library family: structured tags make docs checkable and uniform, at the cost of an extra tool and a style every contributor must follow.
## Why YARD exists **YARD** is a documentation generator for Ruby that reads the same comments RDoc does but adds **tags**: lines that start with `@` and carry structured metadata. RDoc expects free-form prose, so a parameter list is only as consistent as whoever wrote it. YARD parses tags into data, so it can render parameter tables, type lists and exception lists uniformly, warn when documentation disagrees with the code, and count what is undocumented. Plain comments still work: without tags, YARD behaves much like RDoc. ## The core tags for a public method | Tag | Documents | Shape | |---|---|---| | `@param` | a positional **or keyword** argument | `@param name [Types] description` | | `@option` | one key of an options **Hash** argument | `@option opts [Types] :key (default) description` | | `@return` | the return value; repeat it for distinct cases | `@return [Types] description` | | `@raise` | an exception the method may raise | `@raise [ErrorClass] when ...` | | `@example` | usage code, with an optional title | title line, then indented code | | `@yield`, `@yieldparam`, `@yieldreturn` | what the method yields to a block and expects back | `@yieldparam place [Place] ...` | YARD's own documentation is explicit about keyword arguments: use `@param` for them, not `@option`. `@option` belongs to the older style of `def geocode(address, opts = {})`, where it documents the keys inside `opts`. ## The types specifier list The bracketed part is a **types specifier list**, a comma-separated, free-form list with conventions: - `[String, nil]` means either a String or `nil`. - `[Array<GeoLookup::Place>]` is an Array of any number of places. - `[Array(Float, Float)]` is an **order-dependent** list: exactly a Float then a Float, a good fit for a `[lat, lng]` pair. - `[Hash{Symbol => String}]` describes keys and values. - `[#to_s]` is a **duck type**: anything that responds to `to_s`. - `[Boolean]` is a convention for `true` or `false`; Ruby has no `Boolean` class. The list is documentation only. YARD does not check it against the running code, and Ruby ignores it entirely. ## A documented method ```ruby # Resolves a free-text address to a place. # # @param address [String] street address or landmark name # @param country [String, nil] ISO 3166 alpha-2 code to bias results # @return [GeoLookup::Place] if a match was found # @return [nil] if the provider found nothing # @raise [GeoLookup::RateLimitError] if the provider answers HTTP 429 # @example Look up a landmark # client.geocode("Brandenburger Tor", country: "DE") def geocode(address, country: nil) end ``` Two `@return` lines are the documented way to describe distinct return cases, each beginning with the condition. ## Links and other tags worth knowing - `{GeoLookup::Place}` or `{Client#reverse}` inside prose becomes a link; `@see` lists related objects or URLs. - `@deprecated Use {#geocode} instead.` marks an API on its way out, and `@since 2.1.0` records when it appeared. - `@note` adds an emphasised note, `@abstract` marks a method subclasses must implement, `@todo` tracks unfinished work. - `@api private` flags internal API, which later lets the output hide it. ## Generating and checking 1. `yard doc` (the same as `yardoc`) parses `lib/**/*.rb` and friends, stores the result in the `.yardoc` directory and writes HTML to `doc/`. 2. Options you always pass, such as `--markup markdown` or extra files after a `-`, go into a `.yardopts` file so every run agrees. 3. YARD **warns** on problems such as `@param tag has unknown parameter name: adress` or an unknown tag like `@returns`, which is how renamed arguments get caught. 4. `yard server` serves the docs locally, and `-r` reparses on each request while you edit. ## Mistakes interviewers listen for - Using `@option` for keyword arguments. - Writing `@returns` (not a YARD tag, so it triggers the unknown-tag warning). - Believing the types are enforced at runtime. - Forgetting that a comment tag cannot see a renamed parameter until YARD runs and warns.
- How do you document a method that GeoLookup defines with define_method, which YARD cannot see as a def?Use a directive, a tag written as `@!name`. `# @!method geocode_batch(addresses)` followed by indented `@param` and `@return` lines creates a documented method object even though no `def` exists. `@!attribute` does the same for generated accessors, and `@!macro` reuses one such block across many generated methods.
- When would you still use @option instead of @param for a keyword?Only when the method takes a real options Hash, as in `def geocode(address, opts = {})`: `@param opts [Hash]` documents the argument and each `@option opts [String] :country` documents a key. For a keyword argument like `country:` the YARD documentation says to use `@param`.
YARD tags are like the labelled fields on a customs form: the same facts could be written as a letter, but boxes for sender, contents and value let an officer, or a machine, check each one and spot the blank or mismatched box.
saying these in an interview costs you the question
- Keyword arguments must be documented with @option, not @param.
- The types in @param brackets are checked when the method is called.
- @returns and @params are the YARD tag names.
- A method can have only one @return tag.
- Boolean in a YARD type means Ruby has a Boolean class.
- yard doc refuses to generate output when a @param name is wrong.