Best Way to Document "Splatted" Parameter with Yard

Best way to document splatted parameter with YARD?

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

How can one document a function with a variable number of arguments in YARD?

The following makes sense because args is an Array inside the method, although none of the params are an Array as such:

# this function doesn’t do anything
#
# @param [Array<Symbol>] args these arguments do something
# @return [nil]
def myfun(*args)
# ...
end

Note the * is dropped from the param name in the comment. This is just to be consistent - args is an Array, but *args is not.

A quick search shows quite a few projects using this style, including inside Yard's own .rb files (e.g. see source for initialize in Verifier class) - although no examples of this convention are given in the guide.

YARD for keyword arguments with default hash

That signature does not use keyword arguments for :date or :start_time. Keyword arguments for those arguments would be specified as something like:

def get_endpoint(date:, start_time:)

@option is specifically meant for specifying options that would be contained within an options Hash in your case params. Since you are using a keyword argument for params I would recommend adding the @param tag for this as well to clearly identify the keyword argument. For Example:

@param params [Hash]  options to be used in request
@option params [String] :date in YYYYMMDD
@option params [Integer] :start_time in Epoch

Documentation for @options just in case.

pass parameters to insided functions

Positional args and kwargs must be splatted separately:

func_in(args...; kwargs...)

Right now, you only pass positional inputs.

If you want to only pass kwargs to a function, you must do (note leading ;)

foo(; kwargs...)

BTW, it is considered good practice to always distinguish kwargs with a leading ;, even when it is not strictly necessary:

foo(x, y, a="hello", b=4)  # legal
foo(x, y; a="hello", b=4) # better style
foo(a="hello", b=4) # legal
foo(; a="hello", b=4) # better style

Response to update: Keyword arguments must either have a default value, or you must provide a value for it when you call the function. You can for example write:

function func_in(x; y=nothing, z=nothing, t1=nothing, t2=nothing, t3=nothing, t4=nothing)

Another problem in your function test_dict, is that you must call it with three positional arguments, two for println and one for func_in, but you are only calling it with two positional arguments.

This will work:

function func_in(x; y=nothing, z=nothing, t1=nothing, t2=nothing, t3=nothing, t4=nothing)
println(x + t4)
end

function test_dict(x, y, z; w...) # note: *three* positional args
println(x + y )
func_in(z; w...)
end

test_dict(1, 2, 3; y = 15, t4 = 19) # three positional args

You can also use a named tuple and splat it:

kwargs = (y = 15, t4 = 19)  # named tuple
test_dict(1, 2, 3; kwargs...)

Handling keyword parameters in `method_missing`

method_missing works just like any other method in this regard. When you use a double splat it will slurp any keyword arguments and kwargs will always be a hash:

module Foo
def self.method_missing(*args, **kwargs, &block)
kwargs
end
end
irb(main):049:0> Foo.bar(baz: 'Hello World')
=> {:baz=>"Hello World"}

How to pass array elements as separate method arguments in Ruby?

yes, just use * before array:

my_method(model_name, *["x", "y", "z"])

it will result in:

my_method(model_name, "x", "y", "z")

* is a splat operator.



Related Topics



Leave a reply



Submit