Wouldn't this be "import bar; bar.foo()"?
Wouldn't this be "import bar; bar.foo()"?
However, Ruby does have auto-loading conventions. So you could define “module Baz{ module Bar { def foo end; } }” in “baz/bar.rb” from the root of your project. You should then be able to call “Baz::Bar::foo()” from any other file in your project structure without a “require” at all. This is not standard Ruby IIRC, but Rails and other frameworks use it.
https://github.com/fxn/zeitwerk
It is pretty easy to set it up in any Ruby project.
IMO, this is a downside rather than an upside. It's optimizing for writing rather than reading. This hurts understandability for someone who is not familiar with the code base.
The difference is convention over configuration. In Ruby, if you know the convention, then you know exactly where everything is defined without needing to read it. In Python, you must read all those import statements to know where something is coming from, not to mention write them in the first place.
And if you really need to know where something is defined, you simply ask it.
puts obj.method(:foo).source_location
So IMO, Ruby optimizes for both reading and writing. require 'bar'
foo
because require is a regular method and the argument is a string (I mean, you could pass bar without quotes if the string was in a variable called bar, but that's not the scenario being discussed.)> However, Ruby does have auto-loading conventions. So you could define “module Baz{ module Bar { def foo end; } }” in “baz/bar.rb” from the root of your project. You should then be able to call “Baz::Bar::foo()” from any other file in your project structure without a “require” at all. This is not standard Ruby IIRC
autoload is a Kernel method in Ruby core, so it is standard Ruby, but you have to explicitly register a file to be automatically loaded when a particular method is referenced.
Some systems additionally include code that does this for source files based on path.