Bug #19990
closedCould we reconsider the second argument to Kernel#load?
Description
The documentation of Kernel#load
says:
If the optional wrap parameter is true, the loaded script will be executed under an anonymous module, protecting the calling program’s global namespace. If the optional wrap parameter is a module, the loaded script will be executed under the given module. In no circumstance will any local variables in the loaded file be propagated to the loading environment.
I'd like to ask you to reconsider this feature.
First of all, "protecting the calling program" is not really accomplished because the loaded file may still do this
class ::C # defines ::C regardless of the second argument
end
Another example, if the caller defines a module M
, then the loaded program can also define things in M
:
class M::C # defines ::M::C regardless of the second argument
end
It does not even need a leading ::
.
So, the "protection" is not really there.
In addition to that, this is not transparent for the code being loaded either. For example, let's take this program:
class A
end
module X
::A # could be needed if your own lookup had an A somewhere you want to skip
end
the Ruby programmer expects that to work. But with this feature, on paper, nobody knows if it wil work. How can you ship code confidently?
So, the documentation should say:
It kind of protects, but not really. Also, the loaded file may not work as expected, or may not even be loadable at all.
That hypothetical documentation suggests to me it would be worth revisiting this feature.
In Ruby, as it is today, things are global. The language does not have features to really isolate code as containers do, for example.
I believe the 2nd argument to Kernel#load
steers the API in a direction that is not consistent with the language, and provides a feature that is only partial and cannot satisfy what it promises.
I'd be in favor of deprecating and eventually removing this API.