You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Forward keyword arguments and blocks through cached methods
Generated methods only accepted *args, silently dropping keyword
arguments and blocks. This caused methods with kwargs to break
when wrapped with `cacheable`.
Changes:
- All generated methods now accept *args, **kwargs, &block
- key_format procs receive kwargs as well
- unless proc is resolved once at definition time instead of per-call
- Use Bundler.setup instead of Bundler.require in spec_helper for
Ruby 4.0 compatibility
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
*`target` is the object the method is being called on (`#<GitHubApiAdapter:0x0…0>`)
172
173
*`method_name` is the name of the method being cached (`:star_count`)
173
-
*`method_args` is an array of arguments being passed to the method (`[params]`)
174
+
*`method_args` is an array of positional arguments being passed to the method (`[params]`)
175
+
*`**kwargs` are the keyword arguments being passed to the method
174
176
175
177
Including the method argument(s) allows you to cache different calls to the same method. Without the arguments in the cache key, a call to `star_count('cacheable')` would populate the cache and `star_count('tokenautocomplete')` would return the number of stars for Cacheable instead of what you want.
176
178
177
-
In addition, we're including the current date in the cache key so calling this method tomorrow will return an updated value.
179
+
**Note:** The `key_format` proc only receives keyword arguments that the caller explicitly passes — method defaults are not included. That's why the proc uses `kwargs.fetch(:date, Time.now.strftime('%Y-%m-%d'))` to compute its own default when `date:` is omitted. This ensures the cache key always varies by date.
178
180
179
181
```irb
180
182
> a = GitHubApiAdapter.new
181
183
> a.star_count('cacheable')
182
-
Fetching data from GitHub for cacheable
183
-
=> 19
184
+
Fetching data from GitHub for cacheable (as of 2026-02-26)
185
+
=> 58
184
186
> a.star_count('cacheable')
185
-
=> 19
187
+
=> 58
186
188
> a.star_count('tokenautocomplete')
187
-
Fetching data from GitHub for tokenautocomplete
188
-
=> 1164
189
+
Fetching data from GitHub for tokenautocomplete (as of 2026-02-26)
190
+
=> 1309
189
191
> a.star_count('tokenautocomplete')
190
-
=> 1164
192
+
=> 1309
191
193
192
194
# In this example the follow cache keys are generated:
You can control if a method should be cached by supplying a proc to the `unless:` option which will get the same arguments as `key_format:`. This logic can be defined in a method on the class and the name of the method as a symbol can be passed as well. **Note**: When using a symbol, the first argument, `target`, will not be passed but will be available as `self`.
201
+
You can control if a method should be cached by supplying a proc to the `unless:` option which will get the same arguments as `key_format:` (`target, method_name, method_args, **kwargs`). This logic can be defined in a method on the class and the name of the method as a symbol can be passed as well. **Note**: When using a symbol, the first argument, `target`, will not be passed but will be available as `self`.
200
202
201
203
```ruby
202
204
# From examples/conditional_example.rb
@@ -208,18 +210,19 @@ require 'net/http'
208
210
classGitHubApiAdapter
209
211
includeCacheable
210
212
211
-
cacheable :star_count, unless::growing_fast?, key_format:->(target, method_name, method_args) do
Cacheable.cache_adapter.fetch(__send__(method_names[:key_format_method_name], *args),opts[:cache_options])do# rubocop:disable Lint/UselessDefaultValueArgument -- not Hash#fetch; second arg is cache options (e.g. expires_in) passed to the adapter
Cacheable.cache_adapter.fetch(__send__(method_names[:key_format_method_name], *args, **kwargs),opts[:cache_options])do# rubocop:disable Lint/UselessDefaultValueArgument -- not Hash#fetch; second arg is cache options (e.g. expires_in) passed to the adapter
0 commit comments