Allow comments when reading the JSON cache files (fixes load failure on json 3.0) - #191
Open
bonjourjules wants to merge 1 commit into
Open
Allow comments when reading the JSON cache files (fixes load failure on json 3.0)#191bonjourjules wants to merge 1 commit into
bonjourjules wants to merge 1 commit into
Conversation
`Measured::Cache::JsonWriter` prefixes every cache file it writes with a
`// Do not modify this file directly.` line, which is not valid JSON.
`Measured::Cache::Json#read` relied on the json gem accepting JavaScript
comments by default. json 3.0 turned that off: `allow_comments` now
defaults to `false`, so requiring `measured` raises
JSON::ParserError: unexpected token '//' at line 1 column 1
while loading `cache/length.json`, and the gem cannot be loaded at all.
Under Bundler this surfaces as a `Bundler::GemRequireError` at boot.
Opt back into comments when reading the cache. The option was introduced
in json 2.20 and is silently ignored by older versions, which accept
comments anyway, so this stays compatible with every json version
supported by the gem.
The existing `#read` test passes a payload without the comment header,
which is why the suite did not catch this; add a test that uses the exact
header `JsonWriter` produces.
kmcphillips
approved these changes
Sep 7, 2026
kmcphillips
left a comment
Contributor
There was a problem hiding this comment.
This is a good fix that is backwards compatible.
I think it makes sense to not dump that comment at the top if it is technically invalid. It's important to flag that somehow, but maybe there's another way. But maybe the comment doesn't matter because this library should be the only thing that ever reads that file. 🤷♂️
| decode(JSON.load(File.read(@path), nil, freeze: true)) | ||
| # The cache files written by Measured::Cache::JsonWriter start with a `//` comment line, which is not | ||
| # valid JSON. json < 3.0 accepted comments by default, json >= 3.0 requires opting in. The option is | ||
| # ignored by json < 2.20, where comments are accepted anyway. |
Contributor
There was a problem hiding this comment.
A three line comment is not required to add a single config option. LLMs dump this out, but it makes the codebase less legible, not more.
Author
|
I have signed the CLA! |
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.
Problem
measuredcannot be loaded at all when json 3.0 is in the bundle:Measured::Cache::JsonWriterprefixes every cache file with a comment line:That line is not valid JSON.
Measured::Cache::Json#readworked because the json gem accepted JavaScript comments by default. json 3.0 turned that off:Since
lib/measured.rbrequiresunits/length,units/weightandunits/volume, and each declarescache Measured::Cache::Json, "<unit>.json", the table is read while the class body is evaluated — so this raises at require time, not on first conversion. Under Bundler it surfaces asBundler::GemRequireErrorand the host application never boots.This currently affects any app that pulls in
measuredon json 3.0. Because the gemspec declares no upper bound on json, Bundler resolves to 3.0 on its own.The test suite is affected too — on
main, with json 3.0, it does not even load:Fix
Opt back into comments when reading the cache.
allow_commentswas introduced in json 2.20 and unknown options are silently ignored by earlier versions, which accept comments anyway. I verified the call on json 2.19.0, 2.21.2 and 3.0.0 — all three return the parsed table, so this stays compatible across every json version the gem supports (gemspec: Ruby >= 3.0).I kept the writer as is, so cache files already on disk keep working. Dropping the comment header instead would have been the other option, but it breaks reading any previously generated cache.
Verification
With the patch, on json 3.0.0:
The existing
#readtest passes a payload without the comment header, which is why the suite never caught this. I added a test that uses the exact headerJsonWriterwrites, so the regression is covered — it reproduces the failure without the one-line change.