Skip to content

module_function without arguments is not applied to subsequent method definitions #1823

Description

@thyresias

RDoc 8 appears not to handle correctly the no-argument form of Module#module_function.

In Ruby, this:

module M
  module_function

  def foo
  end
end

defines both:

  • M.foo, as a public singleton method;
  • M#foo, as a private instance method.

However, RDoc appears to document foo only as an instance method and does not create/document the corresponding module method M.foo.

After generating the documentation, I would expect M.foo to appear as a module method.

It does not.

Real-world example

This occurs in json 3.0.2.

In lib/json/common.rb, JSON.parse is defined using the no-argument form of module_function:

module JSON
  # ...

  module_function

  # ...

  def parse(source, on_load: nil, object_class: nil, array_class: nil, **options)
    # ...
  end
end

Ruby therefore exposes this method as:

JSON.parse(...)

but RDoc 8 does not appear to document JSON.parse.

Likely cause

RDoc already seems to handle the explicit form:

module_function :foo

by converting an existing method to a module function.

The no-argument form has different semantics: it changes the state of the module so that methods defined subsequently become module functions.

RDoc therefore needs to remember that module_function was called without arguments and apply that state to later def nodes, until the relevant scope ends or the state is otherwise changed.

Conceptually:

module_function

def foo
end

should result in RDoc recording both:

# private instance method
M#foo

# public singleton/module method
M.foo

Notes

This does not appear to be a Prism parsing issue itself: the syntax is parsed normally. The missing part seems to be in RDoc's tracking of the semantic state introduced by a no-argument module_function.

I encountered this while generating documentation for json 3.0.2 with RDoc 8.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions