-
I am curious how I should document the following: Milestone = Data.define(:id, :summary, :status) Such that YARD shows Milestone as a class with the attributes listed above. I can't seem to make it work. |
Beta Was this translation helpful? Give feedback.
Replies: 8 comments
-
Below is the best I can come up with. I don't like how I have to inherit from Data.define. Firstly, it produces a Style/DataInheritance Rubocop violation. The reason this is a Rubocop violation is that an extra class is introduced into the inheritance chain vs. using YARD also gives the following warning:
Additionally, to be complete, I would need to define the initializers and other interesting methods provided by the class returned by Data.define. I am posting this issue to see there there is a better way to document Data objects. # rubocop:disable Style/DataInheritance
# Defines a project milestone
#
# @api public
#
# @!attribute [r] id
# The unique milestone identifier (which is a URL)
# @example
# milestone.id #=> "https://example.com/db/btkkfcemc?a=dr&rid=197"
# @return [String]
#
# @!attribute [r] summary
# A short, one-line milestone summary
#
# A summary is never blank.
#
# @example
# milestone.summary #=> "Doc Storage Requirements Complete"
# @return [String]
# @api public
#
# @!attribute [r] description
# A possibly multi-line / multi-paragraph description of the milestone
#
# May be blank.
#
# @example
# milestone.description #=> "Collaborate with legal on developing doc storage solution"
# @return [String] the description
# @api public
#
class Milestone < Data.define(:id, :summary, :description); end
# rubocop:enable Style/DataInheritance |
Beta Was this translation helpful? Give feedback.
-
You have a few options: The easiest way:...But technically generates an extra runtime parsed line of Ruby. Milestone = Data.define(:id, :summary, :status)
# Defines a project milestone
#
# @api public
#
# @!attribute [r] id
# The unique milestone identifier (which is a URL)
# @example
# milestone.id #=> "https://example.com/db/btkkfcemc?a=dr&rid=197"
# @return [String]
#
# @!attribute [r] summary
# A short, one-line milestone summary
#
# A summary is never blank.
#
# @example
# milestone.summary #=> "Doc Storage Requirements Complete"
# @return [String]
# @api public
#
# @!attribute [r] description
# A possibly multi-line / multi-paragraph description of the milestone
#
# May be blank.
#
# @example
# milestone.description #=> "Collaborate with legal on developing doc storage solution"
# @return [String] the description
# @api public
class Milestone < Data; end The technically correct Ruby way:...But uses very awkward YARD syntax. # @!parse
# # Defines a project milestone
# #
# # @api public
# #
# # @!attribute [r] id
# # The unique milestone identifier (which is a URL)
# # @example
# # milestone.id #=> "https://example.com/db/btkkfcemc?a=dr&rid=197"
# # @return [String]
# #
# # @!attribute [r] summary
# # A short, one-line milestone summary
# #
# # A summary is never blank.
# #
# # @example
# # milestone.summary #=> "Doc Storage Requirements Complete"
# # @return [String]
# # @api public
# #
# # @!attribute [r] description
# # A possibly multi-line / multi-paragraph description of the milestone
# #
# # May be blank.
# #
# # @example
# # milestone.description #=> "Collaborate with legal on developing doc storage solution"
# # @return [String] the description
# # @api public
# class Milestone < Data; end
Milestone = Data.define(:id, :summary, :status) |
Beta Was this translation helpful? Give feedback.
-
Thanks for the response @lsegal! I decided to go with your first example. I don't mind the extra line of Ruby code. In the second example, my IDE doesn't format correctly with the "comments nested in comments". So far as I can tell, the end result in the Ruby runtime environment is the same with or without the the extra One question: in your first example, I don't understand why you can't just replace the last line with: # @!parse class Milestone < Data; end I tried that and Milestone was reported as an undocumented object and in the generated documentation, the Milestone class was there but it only knew that it inherited from Data. None of the other class documentation was there. Thanks for your help! |
Beta Was this translation helpful? Give feedback.
-
I have a similar situation. I have tried every variation of the above that I can, and none of them appear to remove the warning or actually render the correct documentation. I kill the server, delete the I'm using Yard 0.9.34. Here are the ways I've tried. First attempts# @!parse class ModalComponent < LocoMotion::BaseComponent; end
class LocoMotion::Actions::ModalComponent < LocoMotion.configuration.component_class
# Lots of code here
end class LocoMotion::Actions::ModalComponent < LocoMotion.configuration.component_class
# @!parse class ModalComponent < LocoMotion::BaseComponent; end
# Lots of code here
end Same thing, but define the language as Ruby# @!parse ruby class ModalComponent < LocoMotion::BaseComponent; end
class LocoMotion::Actions::ModalComponent < LocoMotion.configuration.component_class
# Lots of code here
end class LocoMotion::Actions::ModalComponent < LocoMotion.configuration.component_class
# @!parse ruby class ModalComponent < LocoMotion::BaseComponent; end
# Lots of code here
end Final attempt: "Technically-correct Ruby way"# @!parse
# # Create a <dialog>-based Modal component.
# # class LocoMotion::Actions::ModalComponent < LocoMotion::BaseComponent; end
class LocoMotion::Actions::ModalComponent < LocoMotion.configuration.component_class # @!parse
# # Create a <dialog>-based Modal component.
# # class ModalComponent < LocoMotion::BaseComponent; end
class LocoMotion::Actions::ModalComponent < LocoMotion.configuration.component_class Edit: As a final note, I know that the |
Beta Was this translation helpful? Give feedback.
-
Ok, based on this comment, it appears that we cannot suppress the warning, and I suppose that is a separate issue we could open / discuss. And after playing with it a bit more, I realized I was going about this the wrong way. Here is the code that did what I wanted: # This is a Modal class!
# @!parse extend LocoMotion::BaseComponent
class LocoMotion::Actions::ModalComponent < LocoMotion.configuration.component_class
end This forces Yard to say that the class inherits from |
Beta Was this translation helpful? Give feedback.
-
Ok...I'm super confused. The above code ( # This is a Modal component.
# @!parse class LocoMotion::Actions::ModalComponent < LocoMotion::BaseComponent; end
class LocoMotion::Actions::ModalComponent < LocoMotion.configuration.component_class
end I guess something was somehow getting cached even though I was deleting the directory every time and re-running the server (maybe something client-side). The only thing I can think of that changed between my first attempts and this latest / working one is that I declared the So maybe Yard was having trouble finding the base class when one of the modules in the inherited class' hierarchy wasn't defined? |
Beta Was this translation helpful? Give feedback.
-
The IMO the solution here is the same as in the referenced issue, namely, you should just be removing the dynamism and defining the superclass directly: class LocoMotion::Actions::ModalComponent < LocoMotion::BaseComponent
end If this is indeed what the superclass is, I don't see the reason to use I don't know much about this library, and I'm probably not in a place to recommend API changes here, but if the superclass is expected to change via user configuration, that is a very brittle and poorly formed API structure. If anything, this is the place where # make sure ModalComponent always contains _at least_ the features of BaseComponent
class LocoMotion::Actions::ModalComponent < LocoMotion::BaseComponent
include LocoMotion.configuration.component_class # allow extra component logic to be included
end Of course, the cleanest way to allow for custom extensions would be to simply allow your downstream consumers to |
Beta Was this translation helpful? Give feedback.
-
@lsegal Yeah, the point of the configuration was allowing downstream users to change the base component class to their I'm not actually sure we will need this, so maybe it's best to hold off on this (or similar) functionality for later. Ultimately, though, I did get it working using the Thanks for your response! |
Beta Was this translation helpful? Give feedback.
The
extend
keyword in Ruby does not define a superclass, it defines a mixin. Mixins are defined in parallel to class hierarcy. YARD would list the mixin as one of the ancestors, but it shouldn't be listing it as as the base class. Indeed following the steps in the comment you referenced is the correct way to do this, namely defining the class, not using extend. More importantly, extend applies to the metaclass, so it's not even really changing the ancestor chain of the class in the way you'd think (it's a bit meta).IMO the solution here is the same as in the referenced issue, namely, you should just be removing the dynamism and defining the superclass directly: