
Issue #21334 has been updated by fxn (Xavier Noria).
If you call something like ref.http_client.fetch, the method fetch is executed in the context of the namespace where http_client lives. That's the namespace where blank? is defined. So in that case, the call should work.
`blank?` was defined in the main namespace, `m` is running in the "foo" namespace, therefore _within_ that namespace `String#blank?` does not exist. I do not provide code because these are thought experiments. People working on namespaces are going to read, nod, and think about it. Tickets for namespaces like this one are not normal tickets due to the special and preliminary nature of the feature. If there is a time to reconsider, it is now that has been exposed to the public. I am not reporting a regular bug in regular code. ---------------------------------------- Bug #21334: Namespaces and object reference sharing https://bugs.ruby-lang.org/issues/21334#change-113223 * Author: fxn (Xavier Noria) * Status: Rejected * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- # Implications related to builtin classes and modules As we know, when a namespace is created, builtin classes in the namespace are as in the root one. This applies to all references to them, explicit or implicit. This is at the core of the current implementation and semantics of namespaces. However, the feature also allow object references to cross namespaces. For example, via method calls: ```ruby ns::Foo.m(ref) ``` And this has implications that do not seem good to me. Examples: 1. If `ref` has an HTTP client in an attribute, that depends on a parser gem, which depends on a string utils gem, that adds `blank?` to `String`, that call is broken because the transitive code at some point may perhaps hit a `blank?` call, and the user has no way to tell. 2. If `ref` is a reference created by a gem managed by Zeitwerk (there are hundreds), the call is broken too. When `m` uses `ref`, it might need to lazy load something, and that won't work because the [Kernel#require](https://github.com/fxn/zeitwerk/blob/main/lib/zeitwerk/core_ext/kernel.rb) and [Module#const_added](https://github.com/fxn/zeitwerk/blob/main/lib/zeitwerk/core_ext/module.rb) decorations are gone within the namespace. Please, note whether a gem loads with Zeitwerk or not is transparent to the user of the gem, by design. How do gems load their code is a private matter that is not, and should not be, documented. So the user does not know. # Implications related to different gem versions In the example above, `ref` could be an instance of an object that corresponds to v2.0 of a gem, and perhaps the code under the namespace has a transitive dependency on v1.0. Mixing such references seems like a receipt for a good amount of Paracetamol. # Proposal This is all so brittle, that I would like to ask for a fundamental reconsideration of cross-namespace object reference passing. The rules are consistent within a namespace, problem is opening that up to cross-namespace communication. Maybe redefine communication across namespaces in a very restrictive way that make these issues by design. Maybe remove cross-namespace communication in this manner altogether. Or some other option people can think of. -- https://bugs.ruby-lang.org/