12

I have a method that should take 1+ parameters of any class, similar to Array#push:

def my_push(*objects)
  raise ArgumentError, 'Needs 1+ arguments' if objects.empty?
  objects.each do |obj| 
    puts "An object was pushed: #{obj.inspect}"
    @my_array.push obj
  end
end

What is the best way to document the method parameters using YARD syntax?

Edit:

I realize that my original question was a bit too vague and didn't quite specify what I was looking for.

A better question would be, what is the best way to specify the arity of a method (1-∞ in this case) in YARD when using a splatted parameter? I know I could just specify it in the text, but it seems like there should be a tag or something similar to specify arity.

hololeap
  • 1,156
  • 13
  • 20

1 Answers1

9

YARD's creator, lsegal, states that the appropriate thing to do is provide an @overload for expected invocations. However, this doesn't really provide much clarity in the case of an Array#push-like method.

I suggest that you use the @param tag and use Array<Object> as the argument type or provide an @overload that looks nice.

Here's a comparison of the two:

class Test
  # A test method
  #
  # @param [Array<Object>] *args Any number of Objects to push into this collection
  # @return nil
  def push(*args); end

  # Another test method
  #
  # @overload push2(obj, ...)
  #   @param [Object] obj An Object to push
  #   @param [Object] ... More Objects
  def push2(*args); end
end
davemyron
  • 2,483
  • 3
  • 24
  • 33
  • 3
    I updated my question to be a bit more specific. The only problem with `Array` is that it implies that an empty list of params is acceptable. `@overload` seems like it is more for specifying different method invocations that have vastly different types of parameters. – hololeap Jun 02 '15 at 22:08
  • 1
    I still think that `overload` would be the most appropriate (and available) tag, especially since there's no _technical_ reason that the method can't accept an empty list (from a method definition perspective) - the docs for it look very appropriate: http://www.rubydoc.info/gems/yard/file/docs/Tags.md#overload. What if you changed the method definition to something like `my_push(first_object, *more_objects)` and then combine & flatten them. Not pretty, I admit, but does get the enforceable arity… – davemyron Jun 09 '15 at 15:20
  • The problem I see with `@param [Array]` is that the splat wraps a non-splatted Array argument into an Array: `def push3(*args); args.inspect end; push3([]) # => [[]]` ***Edit**: I completely fail to convince SO to format a multi-line comment block* – Carsten Sep 13 '16 at 08:31
  • FWIW, [YARD's own docs](https://rubydoc.info/gems/yard/0.9.27/YARD%2FVerifier:initialize) ([source](https://github.com/lsegal/yard/blob/v0.9.27/lib/yard/verifier.rb#L44-L51)) just use `Array` in this case, and expect the reader to note the `*` in the method signature. (From [this answer](https://stackoverflow.com/a/23328895/27358).) – David Moles Jan 26 '22 at 22:35