Skip to content

Commit 44949f5

Browse files
agrbergclaude
andcommitted
Add CLAUDE.md for Claude Code guidance
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 8dc4fb0 commit 44949f5

1 file changed

Lines changed: 67 additions & 0 deletions

File tree

CLAUDE.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project
6+
7+
Cacheable is a Ruby gem by Splitwise that adds method caching via an AOP (Aspect-Oriented Programming) pattern. Include `Cacheable` in a class, annotate methods with `cacheable :method_name`, and results are automatically cached.
8+
9+
## Commands
10+
11+
```bash
12+
# Install dependencies
13+
bundle install
14+
15+
# Run full default task (rubocop + rspec)
16+
bundle exec rake
17+
18+
# Run tests only
19+
bundle exec rspec
20+
21+
# Run a single test file
22+
bundle exec rspec spec/cacheable/cacheable_spec.rb
23+
24+
# Run a single test by line number
25+
bundle exec rspec spec/cacheable/cacheable_spec.rb:45
26+
27+
# Run linter only
28+
bundle exec rubocop
29+
30+
# Auto-fix lint issues
31+
bundle exec rubocop -a
32+
33+
# Watch and auto-run tests/lint on file changes
34+
bundle exec guard
35+
```
36+
37+
## Architecture
38+
39+
The gem uses **module prepending with dynamic method generation** to intercept and cache method calls.
40+
41+
### Core flow
42+
43+
1. **`Cacheable`** (`lib/cacheable.rb`) — The module users include. On `included`, it extends the host class with `MethodGenerator` and creates a unique anonymous interceptor module that gets prepended to the class.
44+
45+
2. **`MethodGenerator`** (`lib/cacheable/method_generator.rb`) — When `cacheable :method_name` is called, this generates five methods on the interceptor module:
46+
- `method_name` (override) — dispatcher that routes to `with_cache` or `without_cache` based on the `unless:` condition
47+
- `method_with_cache` — fetch from cache or compute and store
48+
- `method_without_cache` — bypass cache, call original
49+
- `method_key_format` — generate the cache key
50+
- `clear_method_cache` — invalidate the cache entry
51+
52+
3. **`CacheAdapter`** (`lib/cacheable/cache_adapter.rb`) — Protocol for cache backends. Default is `:memory`. Required interface: `fetch(key, options, &block)` and `delete(key)`.
53+
54+
4. **`MemoryAdapter`** (`lib/cacheable/cache_adapters/memory_adapter.rb`) — Built-in hash-backed in-memory cache. Production use typically wires in `Rails.cache` or a custom adapter.
55+
56+
### Key design details
57+
58+
- Each class that includes `Cacheable` gets its own unique interceptor module (created via `Module.new`), which is prepended to the class. This is how `super` chains through to the original method.
59+
- The `unless:` option accepts a proc/symbol that, when truthy, skips caching and calls the original method directly.
60+
- `key_format:` accepts a proc receiving `(target, method_name, args, **kwargs)` for custom cache key generation.
61+
62+
## Style
63+
64+
- Max line length: 120 characters
65+
- Max method length: 25 lines
66+
- Rubocop enforced with `NewCops: enable`
67+
- No frozen string literal comments required

0 commit comments

Comments
 (0)