Search code examples
rubyyard

How can I reference the current class as a return type in YARD?


Consider a code like this:

module Foo
  # returns a copy of self
  # @return [ ___ ]
  def returns_new_self
    self.class.new
  end
end

class Bar
  include Foo
end

class Zap
  include Foo
end

With this, Bar.new.returns_new_self will return another Bar, and the same goes with Zap.new.returns_new_self.

I want to have retuns_new_self YARD-documented with a return type.
It will be nice if I could do something like @return [Self] as the Self in Rust.

Can I do something similar?


EDIT: (in reply to @spickermann)

The actual code is like this:

module MultipleItemBehaviour
  # @return [Integer]
  def count; not_implemented end

  # @return [Enumerator]
  def each_count
    return enum_for(:each_count) unless block_given?

    count.times do
      yield single_item
    end
  end

  # @return [ __SELF__ ]
  def single_item; not_implemented end

  private def not_implemented
    raise NotImplementedError, "message"
  end
end

class SomeItemWhichIsABunch
  include MultipleItemBehaviour

  attr_reader :count
  def initialize(count)
    @count = count
  end

  def single_item
    self.class.new(1)
  end
end

SomeItemWhichIsABunch.each_count.take(5).map(&:something)

I understand this is a bit off from OOP (it's better to split that Item to a Container and the concrete Items),
but since it's a bunch of all the same things, and it's the way it is stored in the DB already, I decided I want to return a enumerator like this.


EDIT 2: I am passing the --embed-mixin option to yard. The current result in the includer Class document is like this: (sorry for the different module name) The details part of <code>Bar</code>


Solution

  • Unfortunately, YARD can't do that. The best alternative is being explicit in your Foo#returns_new_self documentation. Personally, I'd be totally fine with something along the lines of

    module Foo
      ##
      # Returns a new instance of the object's class.
      #
      # @return [Object]
      def returns_new_self
        self.class.new
      end
    end
    
    class Bar
      include Foo
    end
    
    class Zap
      include Foo
    end
    

    Which yields the following doc:

    foo documentation bar documentation