From: jean.boussier@...
Date: 2021-05-22T12:09:03+00:00
Subject: [ruby-core:103976] [Ruby master Feature#17881] Add a	Module#const_added callback

Issue #17881 has been updated by byroot (Jean Boussier).


> This would trigger for all constants

Indeed, as it seemed the most consistent API to me. But I'm open to an alternative that would only trigger for `class` / `module`. Not sure how it could be named though.

> which might affect startup quite a bit by having all those extra calls

I haven't measured, but I doubt it would be slower than the current `TracePoint.new(:class)` callback.

> I already see it as a problem for `method_added`

We have that hook defined in our app because of sorbet, and the overhead really isn't that bad.

> I think a JIT doesn't need to give up anything for the :class TracePoint.

Of course, it's only a current MJIT limitation. I only mentioned it because @k0kubun's blog post is what prompted me to look at this again. So it's definitely not the main reason to do this, it could just happen to be a nice side effect. A JIT that strip tracing code, and simply de-optimize when tracing is enabled doesn't seem that far fetched to me.

----------------------------------------
Feature #17881: Add a Module#const_added callback
https://bugs.ruby-lang.org/issues/17881#change-92108

* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
----------------------------------------
### Use case

Autoloaders like `zeitwerk` need a callback when a new class or module is registered in the constant table.

Currently this is implemented with TracePoint's `:class` event. It works, but it is a bit unfortunate to have to use an API intended for debugging to implement production features.
It also has performance implications (albeit relatively minor), and [doesn't play well with MJIT](https://k0kubun.medium.com/ruby-3-jit-can-make-rails-faster-756310f235a).

### Proposal

I believe that if Ruby was to call `Module#const_added` when a constant is registered, Zeitwerk could get rid of TracePoint.

For now I implemented it as: `const_added(const_name)` for similarity with `method_added`. But maybe it could make sense to have the signature be `const_added(const_name, const_value)`.

Also since `method_removed` exists, maybe `const_removed` would need to be added for consistency.

### Links

Patch: https://github.com/ruby/ruby/pull/4521
Zeitwerk side discussion: https://github.com/fxn/zeitwerk/issues/135

cc @k0kubun



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>