But, man, the Python import system is so vastly superior to Ruby's "invisible distributed magic" way of handling the same thing.
The sad part is that there is no reason a good language could't have the good parts of both languages. But here we are...
Python 3 is a much better language than Python 2. More consistent and much better designed.
I miss the Ruby standard library though. All those string, array and hash methods make things so easy. I often get stuck looking for Python equivalents.
> The sad part is that there is no reason a good language could't have the good parts of both languages.
There is: backwards compatibility. Most of the time it's impossible to fix a language because the result would be two different languages that have the same name. Python broke compatibility with version 3 and it is still competing with version 2 to this day. Ruby also did the same thing in version 1.9 but thankfully the scale was much smaller.
As such, you'd gut large parts of the language if you stopped evaluating code on require.
Hi btw! Just now noticed it's you. :) Was thinking to write you an e-mail very soon. Which one do you prefer?
> Hi btw! Just now noticed it's you. :) Was thinking to write you an e-mail very soon. Which one do you prefer?
Sure :) Same old e-mails (also on my HN profile page).
I mean, Javascript's modules also are dynamically executed and then returned as a singleton module object (also cached, so only the first require actually runs the code before the module export). This means you can make a module which requires other modules and monkey patches methods inside them (this is how mocking actually works), wrecking havoc amongst all other dependencies, but library authors just don't.
# a.rb
class A
end
# irb
require 'a'
Object::A.new
All code evaluation modifies global interpreter state. Honestly it's not much better than the C preprocessor's #include directive.A better design: files are always evaluated with a clean interpreter state and they can return values just like methods.
# a.rb
class A
end
A
# irb
a = require 'a'
a.new
This makes all state local to each script by default. Users will only have access to the returned value which can contain anything or nothing. If a module needs to modify existing classes, they could return modules that can be mixed in or metaprogramming methods that perform the modifications when called with the targeted class as parameter. Perhaps existing classes could even be passed as parameter: require 'extensions', Object, Kernel
Of course, these changes would break compatibility with all existing gems. The result would be a completely different language that happens to also be called Ruby.Most modern Ruby code avoids monkey-patching "unasked" unless that is an explicit purpose of the project and using the gem is explicitly "asking for it" in the first place. Providing modules to include or making you explicitly call methods or explicitly require files documented to do optional monkey-patching has been the idiomatic way of handling it for years.
Adding the ability to explicitly provide guarantees that the required code is sandboxed might be useful and might particularly help tooling reason better about the code, but it would have quite little practical effect on most modern Ruby.