Lazy load autoloaded bucket components #678
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Autoloaded Ruby constants will not have corresponding proxy methods on Buckets, since these methods are defined on
const_added
. This PR solves that in two ways:External access
Assuming a runtime environment where none of the constants are loaded by default — such as Rails with Zeitwerk during development — we use a bucket like this:
This call will autoload the
Components
module, but it will not autoload theComponents::Heading
module, since it’s just a method call onComponents
. How we handle this is theComponents
bucket catches the call withmethod_missing
, and then tries to load the constant. If loading the constant is successful, it can call the newly definedHeading
method onComponents
.When included
If we include
Components
and then try to callHeading
, again we will run into the same problem.In this case, though, we can’t use
method_missing
. If you includeComponents
andAnotherBucket
and they both define aHeading
component, you would expectAnotherBucket
’sHeading
component to take precedence overComponents
’Heading
component. If both buckets were using themethod_missing
technique, this precedence would be based on which bucket had their component autoloaded first.So instead, when you include a bucket, we eager-load all that bucket’s components.