こないだgemを作ってて調べたやつのメモ。
前置き
例えば下記のように Hashie::Mash
を継承した Pixela::Response
があるとします
module Pixela require "hashie/mash" # Pixela API response # # @see https://www.rubydoc.info/gems/hashie/Hashie/Hash # @see https://www.rubydoc.info/gems/hashie/Hashie/Mash class Response < Hashie::Mash disable_warnings end end
Hashie::Mash
はさらに Hashie::Hash
や Hash
を継承しているため *1、実際には「 Pixela::Response
< Hashie::Mash
< Hashie::Hash
< Hash
< Object
」という継承関係になります。
これを YARD でリファレンスを生成した場合下記のように、「 Pixela::Response
< Hashie::Mash
< Object
」という継承関係になってしまいます。
これはYARDが Hashie::Mash
の実装を知らないためなんですが、3rd party製のgemの継承関係をどうやってYARDに伝えればいいか困ったので調べました。
解決方法:@!parse
で書く
@!parse
*2 を使うとYARDのコメントの中だけで有効なRubyのコードを書けるので、そこで外部のgemの最低限のクラス定義を書いてやれば表示されるようになります。
# @!parse # module Hashie # # @see https://www.rubydoc.info/gems/hashie/Hashie/Hash # class Hash < ::Hash # end # # # @see https://www.rubydoc.info/gems/hashie/Hashie/Mash # class Mash < Hash # end # end module Pixela require "hashie/mash" # Pixela API response # # @see https://www.rubydoc.info/gems/hashie/Hashie/Hash # @see https://www.rubydoc.info/gems/hashie/Hashie/Mash class Response < Hashie::Mash disable_warnings end end
moduleの外側に書くのがポイントで、 moduleの内側に書くと class Pixela::Hashie::Mash
のようなクラスのリファレンスが作られたので、 @!parse
はスコープを解釈してるらしいです。
実際のパッチとYARDで生成されたリファレンスは下記