The project is in a healthy, maintained state
A RuboCop plugin providing Style/CompactModuleNesting, which enforces a hybrid module/class nesting style: all namespace segments collapsed onto a single `module A::B::C` line, with the innermost class or module nested separately inside it.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

>= 1.72, < 2.0
 Project Readme

rubocop-style-compact_nesting

Gem Version CI Downloads License: MIT

A RuboCop plugin that enforces a hybrid module/class nesting style:

  • All namespace segments are collapsed onto a single module line using ::.
  • When the innermost definition in a wrapper chain is a class, that class is nested separately inside the compact module wrapper.
  • When the chain is entirely modules, every segment is collapsed into a single compact module A::B::C wrapping the body directly.

Canonical form

module A::B::C
  class D
    # ...
  end
end

Examples

# bad
module A
  module B
    class C
      # ...
    end
  end
end

# good
module A::B
  class C
    # ...
  end
end
# bad
class A::B::C
  # ...
end

# good
module A::B
  class C
    # ...
  end
end
# good (no namespace)
class Foo
  # ...
end
# bad
module A
  module B
    module C
    end
  end
end

# good (module-only chain collapses to one compact module)
module A::B::C
end

Installation

# Gemfile
gem 'rubocop-style-compact_nesting', require: false
# .rubocop.yml
plugins:
  - rubocop-style-compact_nesting

The plugin disables Style/ClassAndModuleChildren by default because that cop enforces the opposite layout. If you want it back, re-enable it in your own config:

Style/ClassAndModuleChildren:
  Enabled: true

Requires RuboCop >= 1.72 and Ruby >= 3.1.

Rules

Style/CompactModuleNesting

  • Detects chains of wrapper modules whose body is a single nested module/class ending in a class, and rewrites them to one compact outer module A::B::C with a separately nested innermost class D.
  • Rewrites class A::B::C to module A::B; class C; end; end.
  • Collapses pure module-only chains into a single compact module A::B::C wrapping the body directly.
  • Flags (without autocorrect) files that define more than one top-level module/class.
  • Ignores bare top-level classes/modules with no namespace.
  • Ignores wrapper modules whose body contains anything besides a single nested definition (e.g. constants, methods, or sibling classes).

License

MIT