-->

DRYing yard parameters

2019-04-28 23:47发布

问题:

I've got what i assumed was a fairly basic yard macro usage where i have a Hash structure with a number of options that is shared between multiple functions. I was hoping to use a macro simply to prevent me having to replicate this structure all over the place but it doesn't seem to work like that.

What i expected to work was:

# @macro [new] my_hash
#   @param  $1 [Hash,Array<Hash>] Inputted my_hash
#   @option $1 [String] :a Value for A.
#   @option $1 [String] :b Value for B.
#   @option $1 [String] :c Value for C.

##
# my_func does stuff
# @macro my_hash h1
def my_func h1
end

## 
# other_func does stuff
# @macro my_hash h2
def other_func h2, a, b
end

and have h1 and h2 documented correctly. I think i've figured out that at least the $1 doesn't work like that instead takes from the function itself but i can call the both parameters h1 and replace $1 with h1 in the macro and i still don't get what i want.

The "Defining simple macros" example at http://rubydoc.info/docs/yard/file/docs/Tags.md#macro would indicate that i can do this (note that i find examples with @!macro and some without but neither seem to work).

I don't know a lot about yard but does this just not work? Is there something similar that i can do to achieve my result? is there a debugging function that would explain this as no errors come up in the yard server console?

Thanks

回答1:

As you already specify in the macro that it should be expanded for first parameter of method, than you don't need to specify it when expanding macro. Also it seems to be impossible to tell for which parameter to expand macro. Another thing is that you can skip [new] in this case and seems that it is better to use @!macro instead of @macro.

# @!macro my_hash
#   @param  $1 [Hash,Array<Hash>] Inputted my_hash
#   @option $1 [String] :a Value for A.
#   @option $1 [String] :b Value for B.
#   @option $1 [String] :c Value for C.

##
# my_func does stuff
# @!macro my_hash
def my_func h1
end

##
# other_func does stuff
# @!macro my_hash
def other_func h2, a, b
end


回答2:

I believe you can accomplish what you're looking for using YARDs Reference Tags.

From the docs:

If a tag's data begins with (see OBJECT) it is considered a "reference tag". A reference tag literally copies the tag data by the given tag name from the specified OBJECT. For instance, a method may copy all @param tags from a given object using the reference tag syntax:

# @param [String] user the username for the operation
# @param [String] host the host that this user is associated with
# @param [Time] time the time that this operation took place
def clean(user, host, time = Time.now) end

# @param (see #clean)
def activate(user, host, time = Time.now) end


回答3:

This works with yardoc 0.9.8 (probably any version):

# @!macro my_hash
#   @param  $1 [Hash,Array<Hash>] Inputted my_hash
#   @option $1 [String] :a Value for A.
#   @option $1 [String] :b Value for B.
#   @option $1 [String] :c Value for C.

##
# my_func does stuff
# @macro my_hash
def my_func h1
end

##
# other_func does stuff
# @macro my_hash
def other_func h2, a, b
end

Note the missing exclamation mark ! when calling the macro with @macro. This is the correct yardoc syntax.