Feature #19277
openProject-scoped refinements
Description
Refinements are a great way to isolate patches to the files that rely on them. Nonetheless, I believe the need to explicitly enable refinements in every file that uses them has hindered their adoption. As an inciting example, it’s hard to imagine Rails adopting refinements in their current form and requiring using
calls for Active Support core extensions throughout Rails applications.
I’d like to propose a middle way: allowing a Ruby project (a gem, library, application, etc.) to enable refinements for all of its Ruby files. This would combine the isolation benefits of refinements with the convenience of global monkey-patches.
Projects¶
To do this, we must decide how to identify projects and how they specify their desired refinements. A Ruby project is a directory containing a project configuration file with a special name. (I am intentionally not proposing a specific name for the file here. One will need to be chosen eventually, and suggestions are welcome.) A project configuration file is in Ruby format.
When Ruby loads a script from a file, it searches upwards from the current directory for a project configuration file. For reasons of performance, project configurations may be cached per directory path.
When a project configuration is found, it is evaluated as though it were prepended to the beginning of the currently-loading file. Alternatively, a limited DSL could be provided to the configuration file that prepares interpreter state for the currently-loading file.
Below is an example project configuration:
require "prestige/refinements"
using Prestige::Refinements
For ruby -e
and irb
, the project configuration is searched for beginning from the current working directory.
For Kernel#eval
, the current file’s project configuration is used.
Concerns¶
-
Performance, mainly. This is a significant amount of work to add to hot code paths. I believe the cost could be minimized with sensible caching, though not completely eliminated. I haven’t started implementing this and don’t have measurements of the actual cost yet.
-
Ergonomics. Is this the best way to provide project-scoped refinements? Is the project configuration format appropriate?
Updated by georgeclaghorn (George Claghorn) almost 2 years ago
I didn't mention this in the original issue because it's not the primary motivation for project configuration here, but a secondary benefit of project configuration is affording a place to opt in to new interpreter features (frozen string literals) and breaking language changes (in the manner of Rust editions) at the project level.
Updated by georgeclaghorn (George Claghorn) almost 2 years ago
- Description updated (diff)
Updated by duerst (Martin Dürst) almost 2 years ago
- Related to Feature #19024: Proposal: Import Modules added
Updated by matz (Yukihiro Matsumoto) almost 2 years ago
As @duerst (Martin Dürst) mentioned, we understand the need for (some kind of) package importing, and @shioyama (Chris Salzberg) is now working on it. But we are far away from completion.
I personally feel it is a good idea to combine this package with refinements.
Matz.