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

2

6

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>

Kesley answered 24/5, 2019 at 7:18 Comment(4)
Does YARD actually generate docs for included methods in the including module? I only know that "Methods included from …" section which merely contains links to those methods.Americano
Just out of curiosity: Why do you want to have a dedicated method for that? IMO foo.class.new is shorter and easier to understand than foo.returns_new_self?Demanding
@Americano When you pass (or put in yardopts) the --embed-mixin option, the included methods would be listed in the document with information from the tags and strings.Kesley
@spickermann: This was just a short example, but I am trying to create a way to return lists of itself.. Please see the EDIT for details.Kesley
M
1

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

Morello answered 24/5, 2019 at 8:16 Comment(2)
You seem right..., So because we don't have a Self of __CLASS__ or something like that (or not if I implement some plugin for that), documenting in words may be the best options for now after all?Kesley
Yeah, and I think it's pretty clean, tbh. However, the use case you want is interesting; you might want to submit a feature request or see if such a feature request already exists.Morello
C
1

yardoc does not generate documentation in the way you're describing.

When you generate the documentation, Bar and Zap will have a section that says:

Methods included from Foo

#returns_new_self

#returns_new_self will link to the documentation for Foo, and the documentation for Foo will state the possible return types for that method. The individual classes will not have documentation for that method.

You can still document returns_new_self inside of Foo. Setting the return type to any of the following would be considered valid:

A hard-coded list of values from classes that include the module:

# @return [Bar,Zap]

A superclass of the classes that include the module:

# @return [Object]

The literal void for an undefined return type:

# @return [void]
Chantress answered 24/5, 2019 at 8:16 Comment(2)
self would be misleading here. It is used to mean that the method returns the object itself, i.e. the same instance. This is useful to indicate that a method is chainable (in a DSL, for example). It should not be used to indicate that a method returns a different instance of the same class. I'd be confused if I saw this method return self in the documentation.Morello
You can pass the --embed-mixin option to yard, which outputs #count ⇒ Integer (also: #amount) included from Foo in the document for Bar (sorry for the lack of screenshots), and I wanted to have that section point to the current Bar automatically..Kesley

© 2022 - 2024 — McMap. All rights reserved.