Project

General

Profile

Actions

Feature #19277

open

Project-scoped refinements

Added by georgeclaghorn (George Claghorn) almost 2 years ago. Updated almost 2 years ago.

Status:
Open
Assignee:
-
Target version:
-
[ruby-core:111482]

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?


Related issues 1 (0 open1 closed)

Related to Ruby master - Feature #19024: Proposal: Import ModulesClosedActions

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.

Actions #2

Updated by georgeclaghorn (George Claghorn) almost 2 years ago

  • Description updated (diff)
Actions #3

Updated by duerst (Martin Dürst) almost 2 years ago

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

Actions

Also available in: Atom PDF

Like1
Like0Like0Like0Like0