Skip to content

Remove autoload for constant if the autoload fails#4715

Merged
jeremyevans merged 4 commits into
ruby:masterfrom
jeremyevans:autoload-delete-after-failed-load-15790
Oct 8, 2021
Merged

Remove autoload for constant if the autoload fails#4715
jeremyevans merged 4 commits into
ruby:masterfrom
jeremyevans:autoload-delete-after-failed-load-15790

Conversation

@jeremyevans

Copy link
Copy Markdown
Contributor

Previously, if an autoload failed (the file was loaded, but the
constant was not defined by the autoloaded file). Ruby will try
to autoload again if you delete the autoloaded file from
$LOADED_FEATURES. With this change, the autoload is removed as
soon as it fails.

To handle cases where multiple threads are autoloading, when
deleting an autoload, handle the case where another thread
already deleted it.

Fixes [Bug #15790]

Previously, if an autoload failed (the file was loaded, but the
constant was not defined by the autoloaded file). Ruby will try
to autoload again if you delete the autoloaded file from
$LOADED_FEATURES.  With this change, the autoload is removed as
soon as it fails.

To handle cases where multiple threads are autoloading, when
deleting an autoload, handle the case where another thread
already deleted it.

Fixes [Bug ruby#15790]
@jeremyevans jeremyevans requested a review from nobu August 6, 2021 21:49
@fxn

fxn commented Aug 7, 2021

Copy link
Copy Markdown
Contributor

👍

@eregon

eregon commented Aug 7, 2021

Copy link
Copy Markdown
Member

So this removes the autoload but not the constant? That seems rather unexpected, I think removing the constant would be cleaner.
See https://bugs.ruby-lang.org/issues/15790#note-3

@jeremyevans jeremyevans merged commit 08759ed into ruby:master Oct 8, 2021
@eregon

eregon commented Oct 9, 2021

Copy link
Copy Markdown
Member

NOTE: this PR was updated to actually remove the constant (and by that its associated autoload), that's I think much better, thanks 👍

fxn added a commit to fxn/zeitwerk that referenced this pull request Oct 14, 2021
Before Ruby 3.1, if the file require'd by Module#autoload does not define the
expected constant, parent.constants still contains said constant, and you have
to manually remove_const to fully unload everything.

This changed with ruby/ruby#4715.

Starting with Ruby 3.1, parent.constants no longer includes the constant, and
remove_const raises NameError.

This patch allows Zeitwerk to work correctly in both cases without conditionals.
jamieblynn added a commit to jamieblynn/zeitwerk that referenced this pull request Jan 29, 2022
Before Ruby 3.1, if the file require'd by Module#autoload does not define the
expected constant, parent.constants still contains said constant, and you have
to manually remove_const to fully unload everything.

This changed with ruby/ruby#4715.

Starting with Ruby 3.1, parent.constants no longer includes the constant, and
remove_const raises NameError.

This patch allows Zeitwerk to work correctly in both cases without conditionals.
connorchris831 added a commit to connorchris831/zeitwerk that referenced this pull request Jan 5, 2023
Before Ruby 3.1, if the file require'd by Module#autoload does not define the
expected constant, parent.constants still contains said constant, and you have
to manually remove_const to fully unload everything.

This changed with ruby/ruby#4715.

Starting with Ruby 3.1, parent.constants no longer includes the constant, and
remove_const raises NameError.

This patch allows Zeitwerk to work correctly in both cases without conditionals.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants