Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to skip comment /modeline ? #484

Closed
maxigit opened this issue Feb 3, 2012 · 16 comments
Closed

How to skip comment /modeline ? #484

maxigit opened this issue Feb 3, 2012 · 16 comments

Comments

@maxigit
Copy link

maxigit commented Feb 3, 2012

How can I make yard skip comment at the beginning of a file ?

here is my probleme :
I have a file defining module A

# doc of module A
module A
...
end

and then another file using module A as a namespace with a modeline

#vi: modeline for vim


module A
... stuff

end

The modeline (the first comment line) override the doc of module A. The solution I found so far is to add a dummy object between the comment and module A like

#vi: modeline ...
1

module A
... stuff 
end

I don't like it, because I'm pretty sure this '1' will be removed by other people modifying this file.

Any idea ?

@lsegal
Copy link
Owner

lsegal commented Feb 3, 2012

2 newlines will do it. YARD won't pick up comments with more than 2 blank lines between the comment and object declaration.

@maxigit
Copy link
Author

maxigit commented Feb 3, 2012

Thanks, that work indeed. I thought something like that would work (and I think I tried it too, but apparently not) but couldn't find anything in the doc. Thanks again

@maxigit maxigit closed this as completed Feb 3, 2012
@dmolesUC
Copy link

It would be nice if one could configure YARD to ignore comments with even one blank line, since adding two blank lines starts a fight with Rubocop.

@lsegal
Copy link
Owner

lsegal commented May 29, 2015

@dmolesUC3 seems like that's an issue to open with Rubocop, then. :)

@dmolesUC
Copy link

Not exactly. I can configure Rubocop to allow any number of blank lines or an arbitrary fixed number of blank lines, but there's no way to tell it 'allow only one blank line unless the extra blank line is there to trick YARD into ignoring the above comment'.

@dmolesUC
Copy link

(And frankly I'd rather not have the extra blank line for YARD's sake, either.)

@lsegal
Copy link
Owner

lsegal commented May 29, 2015

@dmolesUC3 it still sounds like a feature request for Rubocop. If that project's goal is to enforce existing code conventions, then it should enforce existing code conventions. Blank lines for documentation is one of these existing code conventions-- YARD has been around for more than 8 years now, and this syntax has always been enforced.

Quite explicitly: YARD will not add syntax to ignore comments. You can read about why in a lot of different places:

I'm sure there are more examples out there.

@dmolesUC
Copy link

I wonder if we're talking past each other? I'm not asking for :nodoc: -- I'm trying to document everything! -- I'm just wishing I could put one blank line after non-documentation comments rather than two. (And in fact I didn't know about the two blank lines trick until I found this issue report via Google.)

Speaking as a newcomer, the fact that there aren't any blank lines in (most of? any of?) the documentation examples makes the existing behavior far from obvious. Writing this...

# This is my class
#
# @!attribute [rw] some_attribute
#   @return [SomeType] something or other
# @!attribute [rw] some_other_attribute
#   @return [SomeType] something or other
# ...(etc.)
class MyClass < MyOtherClass

   # ------------------------------------------------------------
   # Attributes

   attr_reader :some_attribute
   attr_reader :some_other_attribute
   # etc...

   # ------------------------------------------------------------
   # Initializer

   # Creates a new {MyClass}
   #
   # @param whatever [Thing] etc.
   def initialize(whatever:)
     # ...
   end

   # ------------------------------------------------------------
   # Overrides

   # ... etc.

end

...it took me a good fifteen minutes to figure out why :some_attribute wasn't getting documented properly. I don't know, maybe I should be filing a different issue asking for @!attribute tags to take precedence over attr_reader/writer/accessor comments.

@lsegal
Copy link
Owner

lsegal commented May 29, 2015

I wonder if we're talking past each other? I'm not asking for :nodoc:

The problem is that for YARD to do the thing you're wanting, we would have to have a feature that would effectively work like a :nodoc:, even if it wasn't called "nodoc".

I don't know, maybe I should be filing a different issue asking for @!attribute tags to take precedence over attr_reader/writer/accessor comments.

This won't happen either. This is actually against convention as well. I'm not sure who is spreading the idea that people should use @!attribute instead of regular inline code comments, but if you see them tell them to stop :)

The actual convention is: "document your attr_accessor!" See #866

# This is my class
class MyClass < MyOtherClass

    # @return [SomeType] something or other
   attr_reader :some_attribute

    # @return [SomeType] something or other
   attr_reader :some_other_attribute

I'll probably have to pour through our existing docs and make sure to update this accordingly. YARD docs are obviously not making this clear enough, we've had a few users trip up over this recently. a FAQ / other entries would probably clarify.

The other convention, which I think RuboCop is correct in [coincidentally] yelling at you about, is "don't have superfluous line comments"

    # ------------------------------------------------------------
    # Attributes

Is unnecessary and a bad code documentation strategy, IMO. If you find yourself needing visual separation between your different class features, you're probably throwing too much data into one file.

@dmolesUC
Copy link

Okay. Part of the docs problem might be that it's easy to hit the deprecated @attr, @attr_reader, and @attr_writer tags first, which can all only go on the class (correct?), and they all say "Use the more powerful @!attribute directive instead". Which suggests (1) that it's the preferred way to document attributes, and (2) that, in the absence of other information, it should also go on the class.

The @!attribute doc says "The comment containing this directive does not need to be attached to any source", but it's not obvious where you can put it it, even with experimentation -- from what I can tell it works on the class and it works on an attr_accessor, but not on an attr_reader or attr_writer, or else I'm not figuring out how to format it for those cases.

And while I can see how a simple @return suffices for an attr_reader, I'm having more trouble with attr_writer -- I can document it as a method taking a value @param, and that works OK, but the type of the attribute (as opposed to the type of the parameter) becomes Object. (Not that I have a lot of use for attr_writer, but it's the principle of the thing.)

I'm new to Ruby, so maybe attr_xxx are all on their way out of style and this isn't important, but if they're still common, it would be nice if there were explicit examples for those cases.

At any rate, it looks like I can get what I want -- superfluous line comments and all -- by documenting the accessors directly, so long as I don't have any attr_writers, which in real code I don't. :\

@dmolesUC
Copy link

No, I take that back, I do have an occasional use for attr_writer, when the reader method is explicit and has lazy initialization. But I'll live with it.

@lsegal
Copy link
Owner

lsegal commented May 30, 2015

Okay. Part of the docs problem might be that it's easy to hit the deprecated @attr, @attr_reader, and @attr_writer tags first, which can all only go on the class (correct?), and they all say "Use the more powerful @!attribute directive instead". Which suggests (1) that it's the preferred way to document attributes, and (2) that, in the absence of other information, it should also go on the class.

Seems like the @attr tags should be removed to avoid this confusion. It is correct that @attr* must be on the class, it is not correct that directives must be the same.

I'm new to Ruby, so maybe attr_xxx are all on their way out of style and this isn't important, but if they're still common, it would be nice if there were explicit examples for those cases.

attr_* are NOT out of style, they are very much still the convention. We should have examples for this, I agree.

No, I take that back, I do have an occasional use for attr_writer, when the reader method is explicit and has lazy initialization. But I'll live with it.

You can document attr_writers too. Just like any method, you can use @overload to modify the signature:

# @overload value=(val)
#   @param val [String] the value to set
attr_writer :value

@dylanahsmith
Copy link

Both myself and my co-workers have also found it confusing that 2 (rather than 1) blank lines are needed to separate comment from a code object to not have it treated as documentation. Rather than having to deal with this recurring confusion, it actually seems simpler to monkey patch YARD to have it behave as expected.

module YardRubyParserExt
  private

  raise NoMethodError unless YARD::Parser::Ruby::RipperParser.private_method_defined?(:add_comment)
  def add_comment(line, node = nil, *args)
    # YARD requires 2 empty lines between a comment and a node to consider the
    # comment to not be documenting the node. Instead, we only require a single
    # empty line, which seems to be behaviour developers expect.
    if node && line < node.line - 1
      node = nil
    end
    super(line, node, *args)
  end
end

YARD::Parser::Ruby::RipperParser.prepend(YardRubyParserExt)

Obviously having YARD be configurable would be preferred.

@lsegal
Copy link
Owner

lsegal commented Nov 28, 2018

@dylanahsmith you can refer to RDoc (example) for creating this formatting convention that YARD must be able to support. I think a few developers believe that this is the expected behavior because of it.

Obviously having YARD be configurable would be preferred.

I suppose this could be configurable, but I'd be more curious as to what your use case is. Stray comments that are not associated with any object should be pretty rare IMO, and the most typical case would likely be VIM/emacs type header comments at the top of files, which could be handled differently than a generalized newline monkeypatch.

Specifically, you could write a plugin to ignore specific comment lines by their formatting. Writing a custom DocstringParser (by subclassing and pre-processing content)

# place this in some .rb file and load with `--load file.rb` or package as a plugin
class IgnoreVIMDirectiveDocstringParser < YARD::DocstringParser
  def parse_content(content)
    super(content.sub(/\Avi:.*$/, ''))
  end
end

YARD::Docstring.default_parser = IgnoreVIMDirectiveDocstringParser

The above requires no monkeypatching.

@dylanahsmith
Copy link

These comments are meant to give an overview of the internals of the code. These are details that aren't meant to be shown in the documented public interface for the code.

When these comments are placed above a namespace module that is documented elsewhere, then they would override the documentation for that module.

@lsegal
Copy link
Owner

lsegal commented Nov 28, 2018

These comments are meant to give an overview of the internals of the code. These are details that aren't meant to be shown in the documented public interface for the code.

I'd still be curious to see a more concrete example of the use case here. Most of the times I have seen this type of thing, I am really looking at something that is effectively still documentation, just for a different audience. Configuring data for different audiences is something YARD can do by adding an @internal tag for example (via --tag internal --hide-tag internal in your .yardopts) and using it as:

# @internal
#   Internal information about this module ...
module Foo
end

That way you can still decide to show that information when generating documentation for internal audiences (your private API docs).

Alternatively if this is too much overhead, you can just move your comments under the declaration rather than on top, where ideally they are closer to the internals they are describing:

module Foo
  # Internal information about this module ...

  # document the class
  class Bar; end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants