(no title)
jonnytran | 3 years ago
Files and modules in Ruby are two distinct things. While Python makes files one-to-one with modules, Ruby allows you to define as many modules as you like in a file, zero or more.
It's true that if you define a constant at the top-level of a file, it uses the global namespace.
By convention, if you have a file named `foo.rb`, you'd write:
module Foo
# Code here
end
and it's equivalent to what's done in Python. But it also has all the other features.
choward|3 years ago
Let's say a file had a module in it. It can behave differently based on context.
For example, let's say I have a module A that requires modules B and C. Module C could use module B without explicitly pulling it in because modules are just globals. However, if a different module just requires module C but not module B and no other files required B either, then module C would break when it tries to use model B. If modules weren't global B, would have to require it to use it directly regardless but since it doesn't it's easy to get unexpected results.
In ruby a file doesn't have to declare the modules it uses which is why I don't consider them modules but just global namespaces. So if another module that got required earlier happens to require B, then B can be used because it's just a global.
I'm summary, modules in Ruby aren't modules but just global namespaces.
jonnytran|3 years ago
Typically, what you're describing is solved, in different ways depending on your setup. I literally never think about the issue you're describing when using Ruby.
- With Rails/ActiveSupport in development mode: Module B is autoloaded lazily when C refers to it.
- With Rails/ActiveSupport in production mode: All modules are eagerly loaded at startup.
- Plain Ruby: There's a few ways, but most gems simply have a file at the top level that eagerly requires all files when the gem is required. Same with an app.
If startup time becomes an issue, you can configure the autoloading at the top level, and the appropriate file will be required lazily when it's referred to. But at that point, just use ActiveSupport.
hnfong|3 years ago
A require in ruby would just import whatever those files defined in the global space. They may be “modules” (which probably have different meaning in ruby vs Python), but they’re globals nonetheless and inventive coders put all sorts of weird things into the global space instead of following convention of one file one module.
It’s a fundamental philosophical difference between the two languages - is it a good thing to let programmers do the wrong thing? Python makes it hard to do so, Ruby celebrates the flexibility.