Reputation: 2345
Given the following ruby file, foo.rb:
# this is a module comment
module A
# this is a constant comment
B = 'hi'
# this is a class comment
class C
# this is a method comment
# @param [String] name Who to say hi to
# @return [String]
def self.hi(name)
"#{B}, #{name}"
end
end
end
How can one programmatically get the comments associated with particular objects (e.g. {A::C => 'this is a class comment'}
, {B => 'this is a constant comment'}
)?
I would expect YARD.parse(File.read('/path/to/foo.rb'))
or YARD::Parser::SourceParser.parse(File.read('/path/to/foo.rb'))
to do something, but they return empty arrays. YARD::Parser::Ruby::RubyParser.parse(File.read('/path/to/foo.rb'))
returns a YARD::Parser::Ruby::RipperParser
instance that appears to be an AST, but I'd prefer to avoid writing an AST traverser (YARD must have this functionality in order to structure the HTML documentation, but I haven't been able to find it).
(I'm using YARD v0.9.9 in case that's helpful.)
Upvotes: 4
Views: 501
Reputation: 1395
So after playing around a little bit and going through the source of yard, I can understand how yard works. Basically it creates a registry of all code objects after YARD.parse
. We can access it like this,
2.4.1 :033 > YARD.parse('./foo.rb')
=> []
2.4.1 :034 > YARD::Registry.all
=> [#<yardoc module A>, #<yardoc constant A::B>, #<yardoc class A::C>, #<yardoc method A::C.hi>]
2.4.1 :035 > code_objects = YARD::Registry.all.map {|object| {object.name => object.docstring} }.inject(&:merge)
{:A=>"this is a module comment", :B=>"this is a constant comment", :C=>"this is a class comment", :hi=>"this is a method comment"}
2.4.1 :036 > code_objects[:A]
=> "this is a module comment"
You should be able to use this and convert into a method as per your needs.
More here: https://github.com/lsegal/yard/blob/master/lib/yard/registry.rb#L225-L237
Upvotes: 6