Is it ruby convention for all files to be in a module with the folder structure (similar to java packages)?
For example, if I have a file structure that looks like
lib/people/utils
would the files in here have the module structure such as:
module People
module Utils
# some functionality for People::Utils
end
end
The reason I ask is because I've been reading through some rails code, and there seem to be several files that are in a file structure like this, but don't have any module declarations.
I'm guessing this would be so you could use the utility function without having to include People::Utils
.
Is there a convention in ruby as to when modules should be used and when they shouldn't?
Modules are used as namespaces and as mixins. All the classes are modules, but all the modules are not classes. The class can use namespaces, but they cannot use mixins like modules. The name of a module must start with a capital letter.
Indeed, a module can be included in another module or class by using the include , prepend and extend keywords. Before to start this section, feel free to read my article about the Ruby Object Model if you're unfamiliar with the ancestor chain in Ruby.
If you're interested, Ruby implements this by placing the module just above the class in the object's inheritance hierarchy. So if a module has a method with the same name as the class, the class will win. To override a method defined on the class from a module, use prepend instead of include .
Class and Module can not be of same name (Example)
It is the standard in Rails. The way Rails loads your models is by looking on the folder structure to guess where classes are. We have the so called autoload_paths
.
You can find them by calling in your rails console
(this is a bit hacky, there might be an easier way to show them):
app.instance_variable_get(:"@app").instance_variable_get(:"@_all_autoload_paths")
A default Rails app output, without config.autoload_paths += %W(#{config.root}/lib)
in your config/application.rb
config block would look like this:
["/Users/lunks/Code/rsvp/app/assets",
"/Users/lunks/Code/rsvp/app/controllers",
"/Users/lunks/Code/rsvp/app/helpers",
"/Users/lunks/Code/rsvp/app/mailers",
"/Users/lunks/Code/rsvp/app/models"]
So, if you have app/models/something/util.rb
and you call Something::Util
somewhere, it'll look into these paths, find the app/models/
folder with something/util.rb
and load this.
Ruby, on the other hand, doesn't care about that. Autoload in plain Ruby works as described on this page. You'll have to either use Autoload or require the files directly (and folder structure won't mean anything).
It's generally a good idea to put classes and files in a structure like that, because it will make it easier for people to map the name of the class to its definition.
But it can make sense not to do this (ultimately you structure your code however you like). I've occasionally done it when there were lots of small classes all dealing with the same thing, I put them together.
And it can make sense to have a file which does not define a module or class, e.g. a configuration file, or a binary, or a bootstrapping file (file which loads up all the other ones).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With