Skip to content

cask/config: define instance variables in a consistent order - #23388

Merged
MikeMcQuaid merged 1 commit into
mainfrom
cask-config-shape-variations
Aug 1, 2026
Merged

cask/config: define instance variables in a consistent order#23388
MikeMcQuaid merged 1 commit into
mainfrom
cask-config-shape-variations

Conversation

@p-linnane

Copy link
Copy Markdown
Contributor

Follows #22362 by defining all of Cask::Config's instance variables up front in #initialize, in a consistent order, so every instance shares one object shape. One Config is built per Cask, plus more via .from_args, .from_json and #merge.

@default and @env were only assigned when the matching keyword argument was passed, and the five directory accessors created their ivars lazily on first read, so instances took different shape transitions depending on which arguments were given and which accessor was hit first. On main:

$ brew ruby -- -W:performance -I Library/Homebrew -r cask/config -e '%i[default env binarydir manpagedir bash_completion zsh_completion fish_completion].each { |m| Cask::Config.new.public_send(m) }; Cask::Config.new(default: {}); Cask::Config.new(env: {})'
Library/Homebrew/cask/config.rb:125: warning: The class Cask::Config reached 8 shape variations, instance variables accesses will be slower and memory usage increased.
It is recommended to define instance variables in a consistent order, for instance by eagerly defining them all in the #initialize method.

That is silent with this change.

The accessors keep their ||= memoization and the ivars are predeclared as nil, so nothing is computed any earlier than before. Evaluation order in #initialize is unchanged, so an invalid default: still raises before an invalid explicit:.

A config_spec.rb example locks the ivar list and its order so a new lazy ivar added without predeclaring it is caught in CI.


  • Have you followed our Contributing guidelines?
  • Have you checked for other open Pull Requests for the same change?
  • Have you explained what your changes do? Performance claims (e.g. "this is faster") must include Hyperfine benchmarks.
  • Have you explained why you'd like these changes included, not just what they do?
  • For bug fixes, have you given step-by-step brew commands to reproduce the bug?
  • Have you written new tests (excluding integration tests)? Here's an example.
  • Have you successfully run brew lgtm (style, typechecking and tests) locally?

  • I did not use AI/LLM to create this PR, or I disclosed the tool/model below and reviewed its output; I did not attribute commits to AI and will answer maintainer questions and review comments myself without AI/LLM.

Claude Code (Opus 5) drafted the implementation and tests; I reviewed the diff, verified the new spec fails against the old initializer and passes with it, confirmed the warning reproduces on main and is silent here, and ran brew lgtm locally.


Signed-off-by: Patrick Linnane <patrick@linnane.io>
Copilot AI review requested due to automatic review settings July 31, 2026 23:52

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates Cask::Config to eagerly define all instance variables in #initialize (in a consistent order) to avoid Ruby “shape variation” performance warnings and ensure all instances share the same object shape.

Changes:

  • Eagerly defines @default and @env (as nil when not provided) and predeclares memoized directory ivars as nil in #initialize.
  • Simplifies directory accessors by removing inline T.let(...) inside ||= now that ivars are declared up-front.
  • Adds an RSpec example intended to lock the instance variable list/order for regression detection.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
Library/Homebrew/cask/config.rb Predeclares all Cask::Config ivars in #initialize and simplifies memoized directory accessors.
Library/Homebrew/test/cask/config_spec.rb Adds a spec asserting consistent instance variable definition ordering.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread Library/Homebrew/test/cask/config_spec.rb

@MikeMcQuaid MikeMcQuaid left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@MikeMcQuaid
MikeMcQuaid added this pull request to the merge queue Aug 1, 2026
Merged via the queue into main with commit bab1909 Aug 1, 2026
45 checks passed
@MikeMcQuaid
MikeMcQuaid deleted the cask-config-shape-variations branch August 1, 2026 06:57
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