[#114062] [Ruby master Bug#19751] Ruby 3.2.2 Fails to Compile from Source — "martin_vahi (Martin Vahi) via ruby-core" <ruby-core@...>

Issue #19751 has been reported by martin_vahi (Martin Vahi).

9 messages 2023/07/01

[#114064] [Ruby master Feature#19752] Allow `--backtrace-limit` to appear in RUBYOPT — "tomstuart (Tom Stuart) via ruby-core" <ruby-core@...>

SXNzdWUgIzE5NzUyIGhhcyBiZWVuIHJlcG9ydGVkIGJ5IHRvbXN0dWFydCAoVG9tIFN0dWFydCku

8 messages 2023/07/01

[#114070] [Ruby master Bug#19753] IO::Buffer#get_string can't handle negative offset — "noteflakes (Sharon Rosner) via ruby-core" <ruby-core@...>

Issue #19753 has been reported by noteflakes (Sharon Rosner).

10 messages 2023/07/03

[#114072] [Ruby master Bug#19754] `IO::Buffer#get_string` raises unsuitable exception for too large offset — "nobu (Nobuyoshi Nakada) via ruby-core" <ruby-core@...>

Issue #19754 has been reported by nobu (Nobuyoshi Nakada).

7 messages 2023/07/03

[#114074] [Ruby master Feature#19755] Module#class_eval and Binding#eval use caller location by default — "byroot (Jean Boussier) via ruby-core" <ruby-core@...>

Issue #19755 has been reported by byroot (Jean Boussier).

15 messages 2023/07/03

[#114080] [Ruby master Bug#19756] URI::HTTP.build does not accept a host of `_gateway`, but `URI.parse` will. — "postmodern (Hal Brodigan) via ruby-core" <ruby-core@...>

Issue #19756 has been reported by postmodern (Hal Brodigan).

9 messages 2023/07/04

[#114168] [Ruby master Misc#19766] DevMeeting-2023-08-24 — "mame (Yusuke Endoh) via ruby-core" <ruby-core@...>

Issue #19766 has been reported by mame (Yusuke Endoh).

9 messages 2023/07/13

[#114222] [Ruby master Misc#19772] API Naming for YARP compiler — "jemmai (Jemma Issroff) via ruby-core" <ruby-core@...>

Issue #19772 has been reported by jemmai (Jemma Issroff).

31 messages 2023/07/17

[#114276] [Ruby master Bug#19784] String#delete_prefix! problem — "inversion (Yura Babak) via ruby-core" <ruby-core@...>

Issue #19784 has been reported by inversion (Yura Babak).

10 messages 2023/07/25

[#114309] [Ruby master Feature#19787] Add Enumerable#uniq_map, Enumerable::Lazy#uniq_map, Array#uniq_map and Array#uniq_map! — "joshuay03 (Joshua Young) via ruby-core" <ruby-core@...>

Issue #19787 has been reported by joshuay03 (Joshua Young).

7 messages 2023/07/29

[#114319] [Ruby master Feature#19790] Optionally write Ruby crash reports into a file rather than STDERR — "byroot (Jean Boussier) via ruby-core" <ruby-core@...>

SXNzdWUgIzE5NzkwIGhhcyBiZWVuIHJlcG9ydGVkIGJ5IGJ5cm9vdCAoSmVhbiBCb3Vzc2llciku

13 messages 2023/07/31

[ruby-core:114247] [Ruby master Feature#19744] Namespace on read

From: "rubyFeedback (robert heiler) via ruby-core" <ruby-core@...>
Date: 2023-07-21 10:28:25 UTC
List: ruby-core #114247
Issue #19744 has been updated by rubyFeedback (robert heiler).


Just a quick comment to Jeremy's statement:

> In regards to the feature in general, looking at my
> large libraries, all of them use absolute ::
> references at least occasionally

I use :: quite a lot in my gems as well so I can relate 
to this, even though none of my gems are as popular as
jeremy's maintained code base. The biggest one I specifically
have to use :: is for the module called "Colours", as a gem,
where I then use in other gems that I maintain a submodule
called "Colours" as well. So I kind of have to use "::Colours"
to refer to the toplevel variant. It's not a big issue for
me but one has to keep in mind to which submodule/toplevel
module one refers to. I did run into issues of other gems
and "namespaces" though when I had a gem called "configuration"
and referred to it via ::Configuration. Unfortunately "gem install
configuration" was owned by someone else (an existing gem), so
in the end I integrated my "module Configuration" into another gem,
and call into that namespace. So at the least from that point
of view, even if this is not directly related to tagomoris'
use case, I can kind of relate to some of the rationale for
the proposal. If we look at it more globally then this is a bit
similar to refinements, e. g. on the one hand being able to 
modify ALL of ruby at "run-time" (which can be a super-great
feature), but also having more fine-tuned control (such as
via refinements, e. g. telling ruby that we want to refer to
modified core classes and core modules only in a given project's
"namespace", but not modify it outside of that).

----------------------------------------
Feature #19744: Namespace on read
https://bugs.ruby-lang.org/issues/19744#change-103935

* Author: tagomoris (Satoshi Tagomori)
* Status: Open
* Priority: Normal
----------------------------------------
# What is the "Namespace on read"

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 the global namespace. Dependencies of required/loaded libraries are also required/loaded in the namespace.

### Motivation

The "namespace on read" can solve the 2 problems below, and can make a path to solve another problem:
The details of those motivations are described in the below section ("Motivation details").

#### 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.

#### (In the future) 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.

### Example code with this feature

```ruby
# your_module
module YourModule
end

# my_module.rb
require 'your_module'

module MyModule
end

# example.rb
namespace1 = NameSpace.new
namespace1.require('my_module') #=> true

namespace1::MyModule #=> #<Module:0x00000001027ea650>::MyModule (or #<NameSpace:0x00...>::MyModule ?)
namespace1::YourModule # similar to the above

MyModule # NameError
YourModule # NameError

namespace2 = NameSpace.new      # Any number of namespaces can be defined
namespace2.require('my_module') # Different library "instance" from namespace1

require 'my_module' # require in the global namespace

MyModule.object_id != namespace1::MyModule.object_id #=> true
namespace1::MyModule.object_id != namespace2::MyModule.object_id
```

The required/loaded libraries will define different "instances" of modules/classes in those namespaces (just like the "wrapper" 2nd argument of `Kernel.load`). This doesn't introduce compatibility problems if all libraries use relative name resolution (without forced top-level reference like `::Name`).

# "On read": optional, user-driven feature

"On read" is a key thing of this feature. That means:

* No changes are required in existing/new libraries (except for limited cases, described below)
* No changes are required in applications if it doesn't need namespaces
* Users can enable/use namespaces just for limited code in the whole library/application

Users can start using this feature step by step (if they want it) without any big jumps.

## Motivation details

This feature can solve multiple problems I have in writing/executing Ruby code. Those are from the 3 problems I mentioned above: name conflicts, globally shared modules, and library version conflicts between dependencies. I'll describe 4 scenarios about those problems.

### Running multiple applications on a Ruby process

Modern computers have many CPU cores and large memory spaces. We sometimes want to have many separate applications (either micro-service architecture or modular monolith). Currently, running those applications require different processes. It requires additional computation costs (especially in developing those applications).

If we have isolated namespaces and can load applications in those namespaces, we'll be able to run apps on a process, with less overhead.

(I want to run many AWS Lambda applications on a process in isolated namespaces.)

### Running tests in isolated namespaces

Tests that require external libraries need many hacks to:

* require a library multiple times
* require many different 3rd party libraries into isolated spaces (those may conflict with each other)

Software with plugin systems (for example, Fluentd) will get benefit from namespaces.

In addition to it, application tests can avoid unexpected side effects if tests are executed in isolated namespaces.

### Safely isolated library instances

Libraries may have globally shared states. For example, [Oj](https://github.com/ohler55/oj) has a global `Obj.default_options` object to change the library behavior. Those options may be changed by any dependency libraries or applications, and it changes the behavior of `Oj` globally, unexpectedly.

For such libraries, we'll be able to instantiate a safe library instance in an isolated namespace.

### Avoiding dependency hells

Modern applications use many libraries, and those libraries require much more dependencies. Those dependencies will cause version conflicts very often. In such cases, application developers should resolve those by updating each libraries, or should just wait for the new release of libraries to conflict those libraries. Sometimes, library maintainers don't release updated versions, and application developers can do nothing.

If namespaces can require/load a library multiple times, it also enables to require/load different versions of a library in a process. It requires the support of rubygems, but namespaces should be a good fundamental of it.

## Expected problems

### Use of top-level references

In my expectation, `::Name` should refer the top-level `Name` in the global namespace. I expect that `::ENV` should contain the environment variables. But it may cause compatibility problems if library code uses `::MyLibrary` to refer themselves in their deeply nested library code.

### Additional memory consumption

An extension library (dynamically linked library) may be loaded multiple times (by `dlopen` for temporarily copied dll files) to load isolated library "instances" if different namespaces require the same extension library. That consumes additional memory.

In my opinion, additional memory consumption is a minimum cost to realize loading extension libraries multiple times without compatibility issues.

This occurs only when programmers use namespaces. And it's only about libraries that are used in 2 or more namespaces.

### The change of `dlopen` flag about extension libraries

To load an extension library multiple times without conflicting symbols, all extensions should stop sharing symbols globally. Libraries referring symbols from other extension libraries will have to change code & dependencies.

(About the things about extension libraries, [Naruse also wrote an entry](https://naruse.hateblo.jp/entry/2023/05/22/193411).)

# Misc

The proof-of-concept branch is here: https://github.com/tagomoris/ruby/pull/1
It's still work-in-progress branch, especially for extension libraries.




-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/

In This Thread