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"?
CodePudding user response:
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