[#122369] [Ruby Bug#21392] Data classes do not allow overriding #inspect — "austin (Austin Ziegler) via ruby-core" <ruby-core@...>

Issue #21392 has been reported by austin (Austin Ziegler).

8 messages 2025/06/01

[#122411] [Ruby Bug#21396] Set#initialize should call Set#add on items passed in — "tenderlovemaking (Aaron Patterson) via ruby-core" <ruby-core@...>

Issue #21396 has been reported by tenderlovemaking (Aaron Patterson).

12 messages 2025/06/04

[#122506] [Ruby Feature#21435] Kernel#optional as a conditional #then — "Alexander.Senko (Alexander Senko) via ruby-core" <ruby-core@...>

SXNzdWUgIzIxNDM1IGhhcyBiZWVuIHJlcG9ydGVkIGJ5IEFsZXhhbmRlci5TZW5rbyAoQWxleGFu

11 messages 2025/06/10

[#122557] [Ruby Bug#21445] [BUG] push_mark_stack() called for broken object raised since cd9f447be247478d2eb3da985295735cce20cb23 — "yahonda (Yasuo Honda) via ruby-core" <ruby-core@...>

Issue #21445 has been reported by yahonda (Yasuo Honda).

10 messages 2025/06/19

[#122615] [Ruby Misc#21458] Test 'make install'? — "MSP-Greg (Greg L) via ruby-core" <ruby-core@...>

Issue #21458 has been reported by MSP-Greg (Greg L).

11 messages 2025/06/28

[ruby-core:122392] [Ruby Feature#21311] Namespace on read (revised)

From: "Eregon (Benoit Daloze) via ruby-core" <ruby-core@...>
Date: 2025-06-03 14:36:47 UTC
List: ruby-core #122392
Issue #21311 has been updated by Eregon (Benoit Daloze).


> Multiple versions of gems can be required
> * Application developers will have fewer version conflicts between gem dependencies if rubygems/bundler will support the namespace on read. (Support from RubyGems/Bundler and/or other packaging systems will be needed)

I think loading different versions of a gem in a single app is impossible to support with Namespace.
But maybe I'm missing something, let me know if so.
Suppose we have this dependency graph from the Gemfile/Gemfile.lock/gemspec dependencies:
```
App->A->B->[email protected]
      \
       C->[email protected]
```

For A to be able to reference B and C (as `B`/`C` in code), B and C need to be constants of `Object` in the same namespace as `A`.
Because gem `A` refers to `B` with like e.g. `B::Foo.new`, not `ns::B::Foo.new`, and same for `C`.

Similarly, B and C refer to D via just `D`, not `ns::D`.
That means D must be in the same namespace as B, C and A.
That means we can't load 2 versions of `D` with such a dependency graph, but that's precisely where it could be useful and what that motivation claims.

So unless I'm missing something, Namespace is of no help to load different gem versions if there is any gem or even app depending transitively on that gem to load with different versions.
Different gem versions with Namespace is only possible for completely separate apps with then completely separate dependency graphs.

----------------------------------------
Feature #21311: Namespace on read (revised)
https://bugs.ruby-lang.org/issues/21311#change-113562

* Author: tagomoris (Satoshi Tagomori)
* Status: Assigned
* Assignee: tagomoris (Satoshi Tagomori)
* Target version: 3.5
----------------------------------------
This replaces #19744 

## Concept

This proposes a new feature to define virtual top-level namespaces in Ruby. Those namespaces can require/load libraries (either .rb or native extension) separately from other namespaces. Dependencies of required/loaded libraries are also required/loaded in the namespace.

This feature will be disabled by default at first, and will be enabled by an env variable `RUBY_NAMESPACE=1` as an experimental feature.
(It could be enabled by default in the future possibly.)

### "on read" approach

The "on write" approach here is the design to define namespaces on the loaded side. For example, Java packages are defined in the .java files and it is required to separate namespaces from each other. It can be implemented very easily, but it requires all libraries to be updated with the package declaration. (In my opinion, it's almost impossible in the Ruby ecosystem.)

The "on read" approach is to create namespaces and then require/load applications and libraries in them. Programmers can control namespace separation at the "read" time. So, we can introduce the namespace separation incrementally.

## Motivation

The "namespace on read" can solve the 2 problems below, and can make a path to solve another problem:

* Avoiding name conflicts between libraries
  * Applications can require two different libraries safely which use the same module name.
* Avoiding unexpected globally shared modules/objects
  * Applications can make an independent/unshared module instance.
* Multiple versions of gems can be required
  * Application developers will have fewer version conflicts between gem dependencies if rubygems/bundler will support the namespace on read. (Support from RubyGems/Bundler and/or other packaging systems will be needed)

For the motivation details, see [Feature #19744].

## How we can use Namespace

```ruby
# app1.rb
PORT = 2048
class App
  def self.port = ::PORT
  def val = PORT.to_s
end

p App.port # 2048

# app2.rb
class Number
  def double = self * 2
end

PORT = 2048.double
class App
  def self.port = ::PORT
  def val = PORT.double.to_s
end

p App.port # 4096

# main.rb - executed as `ruby main.rb`
ns1 = Namespace.new
ns1.require('./app1') # 2048
ns2 = Namespace.new
ns2.require('./app2') # 4096

PORT = 8080
class App
  def self.port = ::PORT
  def val = PORT.to_s
end

p App.port # 8080
p App.new.val # "8080"

p ns1::App.port # 2048
p ns1::App.new.val # "2048"

p ns2::App.port # 4096
p ns2::App.new.val # "8192"

1.double # NoMethodError
```

## Namespace specification

### Types of namespaces

There are two namespace types, "root" and "user" namespace. "Root" namespace exists solely in a Ruby process, and "user" namespaces can be created as many as Ruby programmers want.

### Root namespace

Root namespace is a unique namespace to be defined when a Ruby process starts. It only contains built-in classes/modules/constants, which are available without any `require` calls, including RubyGems itself (when `--disable-gems` is not specified).

At here, "builtin" classes/modules are classes/modules accessible when users' script evaluation starts, without any require/load calls.

### User namespace

User namespace is a namespace to run users' Ruby scripts. The "main" namespace is the namespace to run the user's `.rb` script specified by the `ruby` command-line argument. Other user namespaces ("optional" namespaces) can be created by `Namespace.new` call.

In user namespace (both main and optional namespaces), built-in class/module definitions are copied from the root namespace, and other new classes/modules are defined in the namespace, separately from other (root/user) namespaces.
The newly defined classes/modules are top-level classes/modules in the main namespace like `App`, but in optional namespaces, classes/modules are defined under the namespace (subclass of Module), like `ns::App`.

In that namespace `ns`, `ns::App` is accessible as `App` (or `::App`). There is no way to access `App` in the main namespace from the code in the different namespace `ns`.

### Constants, class variables and global variables

Constants, Class variables of built-in classes and global variables are also separated by namespace. Values set to class/global variables in a namespace are invisible in other namespaces.

### Methods and procs

Methods defined in a namespace run with the defined namespace, even when called from other namespaces.
Procs created in a namespace run with the defined namespace too.

### Dynamic link libraries

Dynamic link libraries (typically .so files) are also loaded in namespaces as well as .rb files.

### Open class (Changes on built-in classes)

In user namespaces, built-in class definitions can be modified. But those operations are processed as copy-on-write of class definition from the root namespace, and the changed definitions are visible only in the (user) namespace.

Definitions in the root namespace are not modifiable from other namespaces. Methods defined in the root namespace run only with root-namespace definitions.

## Enabling Namespace

Specify `RUBY_NAMESPACE=1` environment variable when starting Ruby processes. `1` is the only valid value here.

Namespace feature can be enabled only when Ruby processes start. Setting `RUBY_NAMESPACE=1` after starting Ruby scripts performs nothing.

## Pull-request

https://github.com/ruby/ruby/pull/13226






-- 
https://bugs.ruby-lang.org/
______________________________________________
 ruby-core mailing list -- [email protected]
 To unsubscribe send an email to [email protected]
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/


In This Thread