The project is in a healthy, maintained state
A RuboCop cop that statically detects Ruby code relying on the pre-Ruby 3.4 Hash#inspect output format (e.g. {:sym=>1}). Ruby 3.4 changed Hash#inspect to produce {sym: 1, "str" => 2}, breaking tests that hardcode the old format. Run as part of `pdk validate` to catch incompatibilities before upgrading to Puppet 9 (Ruby 4).
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

>= 1.72.2, < 2.0
>= 1.45.1, < 2.0
 Project Readme

rubocop-hash_inspect

A RuboCop extension gem that flags Ruby code relying on the legacy (Ruby <= 3.3) Hash#inspect output format. Ruby 3.4 changed Hash#inspect from {:x=>1} to {x: 1}, breaking tests that hardcode the old rocket-syntax form. This cop catches those literals statically during pdk validate so Puppet module authors can fix them before upgrading to Puppet 9 (Ruby 4).

Why This Matters — Ruby 3.4 Hash#inspect Change

Ruby 3.4 (December 2024) changed the output of Hash#inspect:

  • Ruby <= 3.3 (Puppet 8): {:x=>1, "baz"=>3}
  • Ruby >= 3.4 (Puppet 9 / Ruby 4): {x: 1, "baz" => 3}

Code that hardcodes the old format in test assertions silently breaks on Puppet 9. This cop detects the legacy rocket-syntax format inside string and regexp literals.

Installation

Add to your Gemfile (development group):

gem 'rubocop-hash_inspect', '~> 0.2', require: false

Then add to your .rubocop.yml (preferred — requires RuboCop >= 1.72):

plugins:
  - rubocop-hash_inspect

Or using the legacy require: directive (compatible with all RuboCop versions):

require:
  - rubocop-hash_inspect

Usage

Once loaded, the cop HashInspect/LegacyHashInspectFormat runs automatically as part of rubocop (or pdk validate when wired via pdk-templates).

Cop: HashInspect/LegacyHashInspectFormat

Flags string, regexp, and interpolated-string literals that contain the legacy Hash#inspect rocket-syntax format ({:sym=>val}), which breaks on Ruby 3.4 / Puppet 9.

Example — flagged (legacy format)

# Legacy format — breaks on Ruby 3.4 / Puppet 9
expect(result.inspect).to eq("{:a=>1}")
expect(msg).to match(/\{:name=>"foo"\}/)

Example — correct

# New format — correct on Ruby >= 3.4
expect(result.inspect).to eq("{a: 1}")
expect(msg).to match(/\{name: "foo"\}/)
# Or better: use a matcher that doesn't depend on inspect output:
expect(result).to eq({ a: 1 })

Offense message

Legacy \Hash#inspect` format (`{:sym=>...}`). Ruby 3.4+ renders hashes as `{sym: ...}`, so this hardcoded value breaks on Ruby 3.4 / Puppet 9. Update it to the new format.`

Disable or configure

# Disable for a specific file (inline):
# rubocop:disable HashInspect/LegacyHashInspectFormat

# Disable globally in .rubocop.yml:
HashInspect/LegacyHashInspectFormat:
  Enabled: false

Development

After checking out the repo, run bin/setup to install dependencies. Then run bundle exec rake to run the spec suite and self-lint together.

bin/setup
bundle exec rake          # spec + self-lint (default task)
bundle exec rake spec     # specs only
bundle exec rake rubocop  # self-lint only

To generate a new cop skeleton:

bundle exec rake 'new_cop[HashInspect/CopName]'

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/puppetlabs/rubocop-hash_inspect.

License

This gem is available as open source under the terms of the Apache License 2.0.