Skip to content

Commit 920bdd4

Browse files
committed
Bump 0.4.0
1 parent ee356c9 commit 920bdd4

3 files changed

Lines changed: 14 additions & 3 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22

33
## master
44

5+
## 0.4.0 (2026-04-29)
6+
7+
- Improved Bootsnap cache invalidation logic on hooks configuration changes.
8+
9+
- Latest Bootsnap compatibility
10+
11+
- Coverage compatibility (w/ some limitations)
12+
513
## 0.3.0 (2026-04-22)
614

715
- Fix the order of around hooks execution (after part) when using `#load_iseq` driven hooks.

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ Require Hooks is a library providing universal interface for injecting custom co
99

1010
Require hooks allows you to interfere with `Kernel#require` (incl. `Kernel#require_relative`) and `Kernel#load`.
1111

12+
> Check the ["Require Hooks: Filling the Gap in Ruby's Extensibility"](https://evilmartians.com/events/require-hooks-rubykaigi) talk from RubyKaigi 2026 to learn more.
13+
1214
<a href="https://evilmartians.com/">
1315
<img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54"></a>
1416

@@ -126,6 +128,7 @@ Thus, if you introduce new source transformers or hijackers, you must invalidate
126128

127129
## Limitations
128130

131+
- Coverage tracking is only supported if `eval` coverage tracking is enabled (`Coverage.start(eval: true, ...)` or `Simplecov.start { enable_coverage_for_eval; ... }`). Currently requires **Ruby 3.4+**.
129132
- `Kernel#load` with a wrap argument (e.g., `load "some_path", true` or `load "some_path", MyModule)`) is not supported (fallbacked to the original implementation). The biggest challenge here is to support constants nesting.
130133
- Some very edgy symlinking scenarios are not supported (unlikely to affect real-world projects).
131134

@@ -175,9 +178,9 @@ Test script: `time bundle exec rails runner 'puts "done"'`.
175178
| rhooks (patch)  | **8m** |
176179
| rhooks (bootsnap)  | 12s |
177180

178-
You can see that requiring tons of files with Require Hooks in patch mode is very slow for now. Why? Mostly because we MUST check `$LOADED_FEATURES` for the presence of the file we want to load and currently we do this via `$LOADED_FEATURES.include?(path)` call, which becomes very slow when `$LOADED_FEATURES` is huge. Thus, we recommend activating Require Hooks after loading all the dependencies and limiting the scope of affected files (via the `patterns` option) on non-MRI platforms to avoid this overhead.
181+
You can see that requiring tons of files with Require Hooks in patch mode is very slow for now. Why? Manipulating the `$LOADED_FEATURES` index from Ruby triggers costly invalidation at the VM side when a regular `#require` occurs. We recommend activating Require Hooks after loading all the dependencies and limiting the scope of affected files (via the `patterns` option) on non-MRI platforms to avoid this overhead.
179182

180-
**NOTE:** Why Ruby's internal implementations is fast despite from doing the same checks? It uses an internal hash table to keep track of the loaded features (`vm->loaded_features_realpaths`), not an array. Unfortunately, it's not accessible from Ruby.
183+
**NOTE:** This could be improved in the future if we get [optimized API](https://github.com/palkan/ruby/pull/1) for managing `$LOADED_FEATURES` from Ruby code.
181184

182185
Here are the numbers for the same project with scoped hooks (only some folders) activated after `Bundler.require(*)`:
183186

lib/require-hooks/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# frozen_string_literal: true
22

33
module RequireHooks
4-
VERSION = "0.3.0"
4+
VERSION = "0.4.0"
55
end

0 commit comments

Comments
 (0)