Repository navigation
Fix collection counter and iteration detection when forwarded through anonymous arguments - #2722
Merged
joelhawksley merged 1 commit intoOct 14, 2026
Conversation
bensheldon
force-pushed
the
collection-initialize-chain
branch
4 times, most recently
from
October 12, 2026 14:40
bea8e06 to
81204e9
Compare
… anonymous arguments
bensheldon
force-pushed
the
collection-initialize-chain
branch
from
October 12, 2026 14:45
81204e9 to
9de81a8
Compare
Contributor
Author
|
Ooh, the ractorization linting is fun 👍🏻 That led me to move stuff around a little more than I expected to, but it's a good direction! |
joelhawksley
approved these changes
Oct 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
The collection introspection checks currently read
instance_method(:initialize).parameters, which only sees the outermostinitialize. When that method forwards its arguments, ViewComponent can't see the signature that actually declares the keywords. This happens with a prepended module.Collection proxy introspection was a barrier to using a prepend-module strategy when I was working on #1106 because I couldn't simply prepend an anonymous-argument-forwarding method on top of a View Component class's
initializewithout regressing the collection behavior.I have 3 PRs in mind for fully landing this improvement:
with_collection_parameterto explicitly declare "send _counter / _iteration parameters" in addition to the introspectionExample:
and with a subclass that forwards to
super:The forwarding method's
**also causes the missing-collection-parameter and reserved-contentchecks to be skipped for prepended modules.What it does
Collect parameters from each
initializeup thesuper_methodchain while the current method takes a keyword splat (**or...), and stop at the first one that only accepts the keywords it names. Forwarding prepended modules ((...),(*, **),(*, foo:, **)) and subclasses that callsuperare then looked through to the signature that declares_counter/_iteration.A prepended module that takes the counter itself (
def initialize(*, item_counter:, **) = super(*, **)) is also detected. Subclasses that narrow their parent's signature (e.g.def initialize(item:) = super(item:, item_counter: 0)) aren't affected, because the walk stops there.When deciding whether a component accepts any keyword, an anonymous
**/...on a prepended module is ignored, because it can only pass keywords along. A named**optionson a prepended module, or a keyword splat on the component itself, still counts, as before.Other details
contentchecks now run against the component's real signature. A component that declarescontent:behind one will now raiseReservedParameterError.prependthat runs after the first collection render or compile isn't picked up.