ruby / ruby/rdoc

module_function without arguments is not applied to subsequent method definitions

Open
#1,823 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
Ruby
Stars
930
Forks
465
Avg merge
3d 10h
Merged PRs (30d)
27

Description

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.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by generating documentation for the example in lib/json/common.rb, then trace RDoc's handling of Module#module_function and its existing explicit-argument path. Check how later def nodes are processed after the no-argument form. Done means subsequent methods appear as private instance methods and public module methods, with regression coverage for the behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
ruby
Domain
documentation
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.