Issue #10320 has been updated by So Wieso.
I chose the symbol `:Lib`, as I thought Ruby would complain if the constant`Lib` would not exist at this time. The keyword `in` would define it, if it would not exist. I would prefer if we could solve it without using symbols, but writing `module Lib; end` before the first require doesn't look nice.
Sorry, I didn't consider that `require` is a method, so I guess the keywordoption (`in`) doesn't fit.
( Alternatively we could define suffix `in` as enclosing the given module:
~~~ruby
require 'file' in Lib
# is equivalent
module Lib
require 'file'
end
~~~
but then require has to check for its nesting.
)
----------------------------------------
Feature #10320: require into module
https://bugs.ruby-lang.org/issues/10320#change-49224
* Author: So Wieso
* Status: Open
* Priority: Normal
* Assignee:
* Category: core
* Target version:
----------------------------------------
When requiring a library, global namespace always gets polluted, at least with one module name. So when requiring a gem with many dependencies, at least one constant enters global namespace per dependency, which can easily get out of hand (especially when gems are not enclosed in a module).
Would it be possible to extend require (and load, require_relative) to put all content into a custom module and not into global namespace?
Syntax ideas:
~~~ruby
require 'libfile', into: :Lib # keyword-argument
require 'libfile' in Lib # with keyword, also defining a module Lib at current binding (unless defined? Lib)
require_qualified 'libfile', :Lib
~~~
This would also make including code into libraries much easier, as it is well scoped.
~~~ruby
module MyGem
require 'needed' in Need
def do_something
Need::important.process!
end
end
# library user is never concerned over needed's content
~~~
Some problems to discuss:
* requiring into two different modules means loading the file twice?
* monkeypatching libraries should only affect the module вк auto refinements?
* maybe also allow a binding as argument, not only a module?
* privately require, so that required constants and methods are not accessible from the outside of a module (seems to difficult)
* what about $global constants, read them from global scope but copy-write them only to local scope?
Similar issue:
https://bugs.ruby-lang.org/issues/5643
--
https://bugs.ruby-lang.org/