0

I've been assigned to perform some maintenance on an existing Ruby gem project. I'm not native to Ruby, but there are files that to me appear to be unnecessary.

Let's say that folder a/b/c is the root of the project, representing module A::B::C. There are also sub modules A::B::C::D1, A::B::C::D2, A::B::C::D3, etc.

The first file that I don't find logical is file modules.rb in folder a/b/c. This contains an empty module declaration for every module in the entire project:

module A::B::C
end

module A::B::C::D1
end

module A::B::C::D2
end

# etc

I tried to find out what this file is for, but I couldn't find any mentions anywhere on Google apart from examples where the modules.rb actually contains all of the code (e.g. https://github.com/shrinidhi99/learn-ruby-for-fun/blob/master/Modules.rb, https://borg.garasilabs.org/andrew/ruby-training/-/blob/master/codes/modules.rb, https://zetcode.com/lang/rubytutorial/oop2/). There's also no reference to it anywhere in the project itself. The only thing it appears to achieve is to provide documentation on rubydoc.info. That can probably be inlined in the separate files.


Besides that, most modules M have a matching file m.rb that sits besides the m folder. For example, file a/b/c.rb, a/b/c/d1.rb, etc. This file contains nothing except require statements of all files in the matching module. That means that file a/b/c.rb also has require statements for a/b/c/d1 etc.

There are two sub modules of A::B::C that are not included in these require files, and these modules have several sub modules of their own. That, combined with the fact that each file should just mention it requirements itself, indicates that these require files are completely unnecessary. The only reason I can think of is mentioned here: https://stackoverflow.com/a/26470550/


Am I wrong in thinking that I can simply remove these files, or are they still necessary? Or is this something that's just "the Ruby way"?

Rob Spoor
  • 6,186
  • 1
  • 19
  • 20

1 Answers1

1

Something like this should work. One file -- one class (or module). If you have namespace and there is general logic in it -- separate file for the namespace

# a.rb
Dir[File.join(__dir__, 'a', '*.rb')].each { |f| require f }

module A
  # general A logic here
end
# a/b.rb
Dir[File.join(__dir__, 'b', '*.rb')].each { |f| require f }

module A
  module B
    # general A::B logic here
  end
end
# a/b/c.rb
module A
  module B
    module C
    end
  end
end
# a/b/d.rb
module A
  module B
    module D
    end
  end
end
# x.rb
require_relative 'a'

class X
  include A::B::C
end
mechnicov
  • 12,025
  • 4
  • 33
  • 56
  • Thanks for your answer. Although this is better than the current contents, which have to manually have entries added, it doesn't answer my question. The question was _why_ these files are implemented, not _how_ they should be implemented. But I think that for the require files (`c.rb` etc.) we both answered my question - to let a single require statement import the entire (or at least great parts of) the project. That still leaves the question about `modules.rb` though. – Rob Spoor Apr 18 '22 at 11:22
  • `modules.rb` in your question is not general practice. As you see it's some students projects – mechnicov Apr 18 '22 at 11:34
  • Just what I thought. I think I'm going to delete that one then, and reimplement the require files using what you posted, because it's more future safe. – Rob Spoor Apr 18 '22 at 11:36