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
Setting Mime Type for .Ogv Files in Rails Development Environment
Ruby Selenium Webdriver Unable to Find Mozilla Geckodriver
Duplicating a Ruby Array of Strings
Using Ruby to Generate Sha512 Crypt-Style Hashes Formatted for /Etc/Shadow
Trying to Compare Two Text Files, and Create a Third Based on Information
Parsing Date from Text Using Ruby
How to Run "Bundle Exec Jekyll New ."
Using S3 Presigned-Url for Upload a File That Will Then Have Public-Read Access
Determine the Class to Which a Method Belongs in Rails
Ruby Daemons and Jruby - Alternative Options
How to Reference a Method in Another Ruby Code File
Ruby - Does Array a Contain All Elements of Array B
Create a Human-Readable List with "And" Inserted Before the Last Element from a Ruby List
Activerecords Select(:Id).Collect VS. Pluck(:Id) Methods: Why Is Pure Ar "Pluck" Slower
Grabbing Snapshots from Webcams in Ruby
In Ruby How to Automatically Populate Instance Variables Somehow in the Initialize Method