Skip to content

Add memoize: true option for per-instance caching#22

Open
agrberg wants to merge 1 commit intoar/hangin_with_claudefrom
ar/memoize-option
Open

Add memoize: true option for per-instance caching#22
agrberg wants to merge 1 commit intoar/hangin_with_claudefrom
ar/memoize-option

Conversation

@agrberg
Copy link
Collaborator

@agrberg agrberg commented Feb 27, 2026

Summary

  • Adds a memoize: true option to cacheable that stores deserialized values directly on the instance, skipping the cache adapter on repeated calls
  • Memoized values are keyed by cache key (matching adapter identity semantics) and cleared automatically by clear_*_cache
  • Zero overhead when memoize is not used — the feature is fully opt-in

Closes #15

Context

When using a serializing cache backend (Redis, Memcached), every call to a cached method pays the deserialization cost via Marshal.load. For expensive objects like ActiveRecord models, this becomes a bottleneck when the same method is called repeatedly within a single request. With memoize: true, the first call fetches from the adapter as usual, but subsequent calls on the same instance return the already-deserialized object directly.

Test plan

  • All 73 existing + new tests pass (bundle exec rspec)
  • RuboCop clean (bundle exec rubocop)
  • Example script runs and demonstrates adapter hit difference (bundle exec ruby examples/memoize_example.rb)
  • Verify behavior with a real serializing adapter (e.g., Rails.cache backed by Redis)

🤖 Generated with Claude Code

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds an opt-in memoize: true mode to cacheable to avoid repeated cache-adapter fetch/deserialization by storing the deserialized result on the receiver (instance or class object) for the lifetime of that receiver.

Changes:

  • Add per-receiver memoization to generated cacheable methods, keyed by computed cache key.
  • Add a Cacheable::MEMOIZE_NOT_SET sentinel to correctly memoize nil/false.
  • Add RSpec coverage, README documentation, and an example script demonstrating reduced adapter hits.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
lib/cacheable/method_generator.rb Implements memoization fast-path and memo store writes; hooks memo clearing into clear_*_cache.
lib/cacheable.rb Introduces sentinel constant used by memoization to distinguish “unset” from nil/false.
spec/cacheable/cacheable_spec.rb Adds tests covering memoization behavior (adapter hit reduction, nil/false, unless, clearing, class methods).
README.md Documents memoize: true, usage, and caveats around object lifetime / staleness.
examples/memoize_example.rb Demonstrates adapter-hit difference with and without memoization.

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

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.


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

When `memoize: true` is passed to `cacheable`, repeated calls on the
same instance skip the cache adapter entirely and return the previously
deserialized result. This avoids expensive repeated deserialization for
objects like ActiveRecord models. Memoized values are cleared by
`clear_*_cache` and garbage collected with the instance.

Closes #15

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.


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

@agrberg
Copy link
Collaborator Author

agrberg commented Feb 27, 2026

This branch should address and close our last open issue. To be merged after #21

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.

2 participants