mize 0.6.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9907846af04f5b779a69892b22ffc90f80172a4c0949a28b2b20c8c5d505f3a5
4
- data.tar.gz: f18d5f411c014669d5b3a7b7d46a127f0f03522aff97b79cf916b3ee67e58563
3
+ metadata.gz: '04349dcaaaec8f657183fc213be81b6c49f182d0687441b7cdd004e561a008a4'
4
+ data.tar.gz: 89f29be0ec81a2d25c4418d818e89afa40e4699529f4d04feccffabb4a0225dc
5
5
  SHA512:
6
- metadata.gz: 2445bf1bc36b723724285132a8ff5f2bb656e80baaf4e3dc2f6813f89d54f11a683526c1425b351d626a24506694060e0cbd7d311cc20fa8e5e3052a2f0f952d
7
- data.tar.gz: 1f3873dd7ccee1ee81e7af7a593b0ab3b068b51f3140c08e80454878e4b83e3e9a5086632405af0975f900c24b9e668fce35f70f672fa1f98ecdd6ed30affd41
6
+ metadata.gz: 6e4ea031b167f232db72a768d892884ea6516b4d1f68603b2e992c95bfed16509838e7df6fc64142944cc5009fff8472a08ede1f88b4767e25e1df9fa2cc980b
7
+ data.tar.gz: a0790fa35f0ac32bd68679670cbdb45efb4173ef1140865ac64f2e891edc8ca49ad6ceb502dedebe87b7897eb64606cbfd7817eebe6f6033f56b693338d27564
data/.all_images.yml CHANGED
@@ -1,27 +1,33 @@
1
1
  dockerfile: |-
2
- RUN apk add --no-cache build-base git bash
3
- RUN bash <<NUR
4
- if [[ "$(ruby -e 'print RUBY_VERSION')" > '3' ]]
5
- then
6
- gem update --system
7
- gem install gem_hadar bundler
8
- else
9
- gem install gem_hadar
10
- gem install bundler -v 2.4.22
11
- fi
12
- NUR
2
+ RUN apk add --no-cache build-base yaml-dev git openssl-dev
13
3
 
14
4
  script: &script |-
15
5
  echo -e "\e[1m"
16
6
  ruby -v
17
7
  echo -e "\e[0m"
18
- bundle install --full-index
8
+ bundle install --jobs=$(getconf _NPROCESSORS_ONLN)
19
9
  bundle exec rake spec
20
10
 
21
- fail_fast: yes
11
+ before: |-
12
+ echo 🏁 Preparing…
13
+ echo Deleting Gemfile.lock
14
+ rm -f Gemfile.lock
15
+
16
+ after: |-
17
+ if [[ "$RESULT" = "1" ]]
18
+ then
19
+ echo 😵 Some tests failed!
20
+ else
21
+ echo 🥳 All tests passed!
22
+ fi
23
+ echo Deleting Gemfile.lock
24
+ rm -f Gemfile.lock
25
+
26
+ fail_fast: true
22
27
 
23
28
  images:
29
+ ruby:4.0-alpine: *script
30
+ ruby:3.4-alpine: *script
24
31
  ruby:3.3-alpine: *script
25
32
  ruby:3.2-alpine: *script
26
33
  ruby:3.1-alpine: *script
27
- ruby:3.0-alpine: *script
@@ -0,0 +1,51 @@
1
+ # Simple workflow for deploying static content to GitHub Pages
2
+ name: Deploy static content to Pages
3
+
4
+ on:
5
+ # Runs on pushes targeting the default branch
6
+ push:
7
+ branches: [ "master" ]
8
+
9
+ # Allows you to run this workflow manually from the Actions tab
10
+ workflow_dispatch:
11
+
12
+ # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
13
+ permissions:
14
+ contents: read
15
+ pages: write
16
+ id-token: write
17
+
18
+ # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
19
+ # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
20
+ concurrency:
21
+ group: "pages"
22
+ cancel-in-progress: false
23
+
24
+ jobs:
25
+ # Single deploy job since we're just deploying
26
+ deploy:
27
+ environment:
28
+ name: github-pages
29
+ url: ${{ steps.deployment.outputs.page_url }}
30
+ runs-on: ubuntu-latest
31
+ steps:
32
+ - name: Checkout
33
+ uses: actions/checkout@v6
34
+ - name: Setup Pages
35
+ uses: actions/configure-pages@v6
36
+ - name: Setup Ruby
37
+ uses: ruby/setup-ruby@v1
38
+ with:
39
+ ruby-version: '4.0'
40
+ - name: Generate Documentation
41
+ run: |
42
+ gem install gem_hadar
43
+ bundle install
44
+ rake doc
45
+ - name: Upload artifact
46
+ uses: actions/upload-pages-artifact@v5
47
+ with:
48
+ path: 'doc'
49
+ - name: Deploy to GitHub Pages
50
+ id: deployment
51
+ uses: actions/deploy-pages@v5
data/.rspec CHANGED
@@ -1,2 +1,3 @@
1
1
  --color
2
2
  -fd
3
+ -rspec_helper
data/CHANGES.md CHANGED
@@ -1,5 +1,67 @@
1
1
  # Changes
2
2
 
3
+ ## 2026-10-18 v0.7.0
4
+
5
+ ### Breaking
6
+ - Removed support for Ruby **3.0** from the CI test matrix.
7
+ - Removed the vestigial `MonitorMixin` inclusion from `Mize::DefaultCache`, as
8
+ the class is now a plain `Hash` wrapper relying on the GVL for atomicity.
9
+
10
+ ### Features
11
+ - Added `Mize.synchronize` API to expose the internal `MUTEX` for atomic
12
+ multi-step operations, with specific handling for `ThreadError` in trap
13
+ contexts.
14
+ - Added a GitHub Actions workflow (`static.yml`) to generate YARD documentation
15
+ and deploy it to GitHub Pages.
16
+ - Added `changelog` configuration to the `Rakefile` to enable automated
17
+ generation of `CHANGES.md`.
18
+ - Added `source_code_uri` metadata to the gemspec.
19
+
20
+ ### Improvements
21
+ - Added comprehensive YARD documentation to all library modules (`Mize`,
22
+ `Mize::Memoize`, `Mize::CacheMethods`, `Mize::CacheProtocol`,
23
+ `Mize::Configure`, `Mize::DefaultCache`, `Mize::GlobalClear`,
24
+ `Mize::Railtie`, and `Mize::Reload`).
25
+ - Improved the generated `lib/mize/version.rb` template with module-level and
26
+ constant-level YARD comments.
27
+ - Replaced manual `SimpleCov` initialization in `spec/spec_helper.rb` with
28
+ `gem_hadar/simplecov` and added error handling for missing dependencies.
29
+ - Migrated internal `Mize::MUTEX.synchronize` calls in `global_clear.rb`,
30
+ `memoize.rb`, and `reload.rb` to use the new `Mize.synchronize` API.
31
+ - Removed the obsolete `.utilsrc` configuration file.
32
+ - Removed unused `config/config.yml` and `config/broken_config.yml` files.
33
+ - Corrected the typo "memoziation" to "memoization" in the gem summary and
34
+ description.
35
+
36
+ ### Build & CI
37
+ - Updated CI configuration to support Ruby **4.0** by adding `yaml-dev` and
38
+ `openssl-dev` dependencies and updating the bundler setup.
39
+ - Aligned `.all_images.yml` with standard multi-image configuration, including
40
+ `before`/`after` hooks for `Gemfile.lock` cleanup and result echoing.
41
+ - Updated `gem_hadar` development dependency to **2.20.1**.
42
+ - Updated `rubygems_version` in the gemspec to **4.0.22**.
43
+ - Removed `bundle update --all` from the CI script in favor of `bundle install
44
+ --jobs=$(getconf _NPROCESSORS_ONLN)`.
45
+
46
+ ### Testing
47
+ - Added `spec/mize_spec.rb` to verify `Mize.synchronize` block return values
48
+ and lock identity.
49
+ - Added `-rspec_helper` to `.rspec` and removed explicit `require
50
+ 'spec_helper'` statements from spec files.
51
+
52
+ ### Documentation
53
+ - Restructured `README.md` to cover the full API surface, including options
54
+ (`freeze:`, `store_nil:`), keyword arguments, targeted cache clearing, global
55
+ cache, custom cache backends, and Rails integration.
56
+ - Replaced the introductory text with a concise description and added proper
57
+ fenced code blocks with language tags.
58
+ - Removed the redundant "Download" section, folding the repository link into
59
+ the "Repository" section.
60
+ - Added a "Documentation" section to `README.md` linking to the hosted API
61
+ documentation.
62
+ - Updated `README.md` to reflect the removal of `MonitorMixin` from the default
63
+ cache backend description.
64
+
3
65
  ## 2024-10-17 v0.6.1
4
66
 
5
67
  * Remove deprecated Ruby versions:
data/README.md CHANGED
@@ -1,39 +1,31 @@
1
1
  # Mize
2
2
 
3
+ Lightweight memoization for Ruby. Annotate any method or function with a
4
+ single `memoize` call and Mize handles result caching, invalidation, and
5
+ Rails-aware reload for you.
3
6
 
4
- ## Introduction
5
-
6
- Memoization is a powerful technique for improving the performance of
7
- computationally expensive functions or methods by caching and reusing
8
- previously computed results. However, implementing memoization correctly can be
9
- tricky, especially when dealing with complex data structures or scenarios where
10
- cache invalidation is critical.
11
-
12
- ## Description
13
-
14
- The `mize` library provides a simple and flexible way to memoize methods and
15
- functions in Ruby, making it easier for developers to write high-performance
16
- code without the need for manual caching implementations. In this README.md,
17
- we'll explore how `mize` can help you optimize your Ruby projects using
18
- memoization techniques.
7
+ Works with Ruby 3.1 – 4.0 (tested via `.all_images.yml`).
19
8
 
20
9
  ## Installation
21
10
 
22
- You can use rubygems to fetch the gem and install it for you:
23
-
24
- # gem install mize
25
-
26
- You can also put this line into your `Gemfile`
11
+ ```sh
12
+ gem install mize
13
+ ```
27
14
 
28
- gem 'mize'
15
+ or add to your `Gemfile`:
29
16
 
30
- and bundle.
17
+ ```ruby
18
+ gem 'mize'
19
+ ```
31
20
 
32
21
  ## Usage
33
22
 
34
- Memoizes methods, that is the values depend on the receiver, like this:
23
+ ### Memoize a method
35
24
 
36
- ```
25
+ Results are cached **per receiver**. Two different objects get independent
26
+ caches even for identical arguments:
27
+
28
+ ```ruby
37
29
  class A
38
30
  @@c = 0
39
31
 
@@ -45,19 +37,19 @@ end
45
37
 
46
38
  a1 = A.new
47
39
  a1.foo(23) # => "foo 23 1"
48
- a1.foo(23) # => "foo 23 1"
40
+ a1.foo(23) # => "foo 23 1" (cached)
41
+
49
42
  a2 = A.new
50
- a2.foo(23) # => "foo 23 2"
51
- a2.foo(23) # => "foo 23 2"
52
- a2.mize_cache_clear
53
- a2.foo(23) # => "foo 23 3"
54
- a1.foo(23) # => "foo 23 1"
43
+ a2.foo(23) # => "foo 23 2" (different receiver)
44
+ a2.foo(23) # => "foo 23 2" (cached)
55
45
  ```
56
46
 
57
- Memoizes functions, that is the values do not depend on the receiver, like
58
- this:
47
+ ### Memoize a function
59
48
 
60
- ```
49
+ Results are cached **globally** — the receiver is ignored. All instances
50
+ share one cache entry per argument set:
51
+
52
+ ```ruby
61
53
  class B
62
54
  @@c = 0
63
55
 
@@ -69,18 +61,128 @@ end
69
61
 
70
62
  b1 = B.new
71
63
  b1.foo(23) # => "foo 23 1"
72
- b1.foo(23) # => "foo 23 1"
73
64
  b2 = B.new
74
- b2.foo(23) # => "foo 23 1"
75
- b2.foo(23) # => "foo 23 1"
76
- B.mize_cache_clear
77
- b2.foo(23) # => "foo 23 2"
78
- b1.foo(23) # => "foo 23 2"
65
+ b2.foo(23) # => "foo 23 1" (same cache as b1)
66
+ ```
67
+
68
+ ### Options
69
+
70
+ | Option | Default | Effect |
71
+ |:-------------|:--------|:--------------------------------------|
72
+ | `freeze:` | `false` | Freeze the cached result if possible |
73
+ | `store_nil:` | `true` | Cache `nil` results; `false` recomputes |
74
+
75
+ ```ruby
76
+ memoize method:, freeze: true, store_nil: false
77
+ def expensive_query
78
+ # ...
79
+ end
80
+ ```
81
+
82
+ Keyword arguments are supported and included in the cache key:
83
+
84
+ ```ruby
85
+ memoize method:
86
+ def lookup(name, limit: 10)
87
+ # ...
88
+ end
89
+
90
+ lookup("flori") # => computes
91
+ lookup("flori") # => cached
92
+ lookup("flori", limit: 5) # => separate cache entry
93
+ ```
94
+
95
+ ### Clearing the cache
96
+
97
+ Clear a single method's cache entries by name:
98
+
99
+ ```ruby
100
+ a1.mize_cache_clear_name(:foo)
101
+ ```
102
+
103
+ Clear **all** cached entries for a receiver (method memoization) or for the
104
+ class (function memoization):
105
+
106
+ ```ruby
107
+ a1.mize_cache_clear # method: only a1's cache
108
+ B.mize_cache_clear # function: global shared cache
79
109
  ```
80
110
 
81
- ## Download
111
+ ## Global cache clearing
112
+
113
+ `Mize.cache_clear` walks the entire object space for anything including
114
+ `Mize::CacheProtocol` and clears it. Use this in test setups or teardown:
115
+
116
+ ```ruby
117
+ Mize.cache_clear
118
+ ```
119
+
120
+ ## Rails integration
121
+
122
+ When Rails is loaded, Mize registers a railtie that calls
123
+ `Mize.cache_clear` on every `to_prepare` block (i.e. on each code reload in
124
+ development). If your model or class defines a `#reload` method, Mize
125
+ prepends its own `reload` that delegates to `super` and then clears
126
+ memoized entries automatically.
127
+
128
+ ## Custom cache backend
129
+
130
+ The default backend is a plain in-memory `Hash`. Swap in your own
131
+ (e.g. Redis, Memcached) by implementing the
132
+ `Mize::CacheProtocol` interface:
133
+
134
+ ```ruby
135
+ class RedisCache
136
+ include Mize::CacheProtocol
137
+
138
+ def initialize
139
+ @r = Redis.new
140
+ end
141
+
142
+ def read(name, options = nil)
143
+ @r.get("mize:#{name}")
144
+ end
145
+
146
+ def write(name, value, options = nil)
147
+ @r.set("mize:#{name}", Marshal.dump(value))
148
+ end
149
+
150
+ def exist?(name, options = nil)
151
+ !@r.get("mize:#{name}").nil?
152
+ end
153
+
154
+ def delete(name, options = nil)
155
+ @r.del("mize:#{name}")
156
+ end
157
+
158
+ def clear(options = nil)
159
+ # delete matching keys or flushdb
160
+ end
161
+
162
+ def each_name(&block)
163
+ # yield each key
164
+ self
165
+ end
166
+
167
+ def prototype
168
+ dup
169
+ end
170
+ end
171
+
172
+ Mize.configure do
173
+ cache RedisCache.new
174
+ end
175
+ ```
176
+
177
+ Any object that `include Mize::CacheProtocol` and implements `read`,
178
+ `write`, `exist?`, `delete`, `clear`, `each_name`, and `prototype` will
179
+ work.
180
+
181
+ ## Documentation
182
+
183
+ Complete API documentation is available at: [GitHub.io](https://flori.github.io/mize/)
82
184
 
83
- The homepage of this library is located at
185
+ ## Repository
84
186
 
85
187
  * https://github.com/flori/mize
86
188
 
@@ -90,4 +192,4 @@ The homepage of this library is located at
90
192
 
91
193
  ## License
92
194
 
93
- This software is licensed under MIT license.
195
+ MIT
data/Rakefile CHANGED
@@ -7,11 +7,20 @@ GemHadar do
7
7
  author 'Florian Frank'
8
8
  email 'flori@ping.de'
9
9
  homepage "https://github.com/flori/#{name}"
10
- summary 'Library that provides memoziation for methods and functions'
10
+ metadata 'source_code_uri', homepage
11
+ summary 'Library that provides memoization for methods and functions'
11
12
  description "#{summary} for Ruby."
12
13
  readme 'README.md'
13
14
  licenses << 'MIT'
14
15
 
16
+ changelog do
17
+ filename 'CHANGES.md'
18
+ end
19
+
20
+ github_workflows(
21
+ 'static.yml' => { }
22
+ )
23
+
15
24
  test_dir 'spec'
16
25
  yard_dir 'doc'
17
26
 
@@ -19,7 +28,6 @@ GemHadar do
19
28
  '.AppleDouble', 'tags', '.byebug_history', '.yard*', 'yard', 'doc',
20
29
  'errors.lst'
21
30
 
22
-
23
31
  development_dependency 'rake'
24
32
  development_dependency 'simplecov'
25
33
  development_dependency 'rspec'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.1
1
+ 0.7.0
@@ -1,14 +1,28 @@
1
1
  require 'mize/cache_protocol'
2
2
  require 'mize/default_cache'
3
3
 
4
+ # Per-object memoization bookkeeping.
5
+ #
6
+ # Mixed into any module that calls +memoize+. Each *object* gets its own
7
+ # lazily-created cache instance (a copy of +Mize.default_cache+), and the
8
+ # key-building helpers below produce stable, argument-sensitive cache keys.
9
+ #
10
+ # State is deliberately kept per-object: two instances of the same memoized
11
+ # class do not share a cache, which is the expected semantics for instance
12
+ # methods.
4
13
  module Mize::CacheMethods
5
14
  # Clear cached values for all methods/functions of this object.
15
+ #
16
+ # @return [self] The receiver, for chaining.
6
17
  def mize_cache_clear
7
18
  __mize_cache__.clear
8
19
  self
9
20
  end
10
21
 
11
22
  # Clear all cached results for the method/function +name+.
23
+ #
24
+ # @param name [String, Symbol] The name of the memoized method/function.
25
+ # @return [self] The receiver, for chaining.
12
26
  def mize_cache_clear_name(name)
13
27
  name = build_key_prefix(name)
14
28
  __mize_cache__.each_name do |n|
@@ -20,11 +34,19 @@ module Mize::CacheMethods
20
34
  private
21
35
 
22
36
  # Set the cache object to +cache+.
37
+ #
38
+ # @param cache [Mize::CacheProtocol] The cache backend to store in.
39
+ # @return [Mize::CacheProtocol] The cache backend now stored in +self+.
23
40
  def __mize_cache__=(cache)
24
41
  @__mize_cache__ = cache
25
42
  end
26
43
 
27
- # Return the cache object.
44
+ # Return the cache object, creating one on first use.
45
+ #
46
+ # The first access makes a fresh copy of +Mize.default_cache+ (via
47
+ # +prototype+ / "dup") so that each object holds an independent store.
48
+ #
49
+ # @return [Mize::CacheProtocol] This object's cache backend.
28
50
  def __mize_cache__
29
51
  if defined?(@__mize_cache__)
30
52
  @__mize_cache__
@@ -34,16 +56,35 @@ module Mize::CacheMethods
34
56
  end
35
57
 
36
58
  # Build a key prefix for +name+.
59
+ #
60
+ # @param name [String, Symbol] The method/function name.
61
+ # @return [String] The namespaced prefix, e.g. +"mize/foo"+.
37
62
  def build_key_prefix(name)
38
63
  "mize/#{name}"
39
64
  end
40
65
 
41
66
  # Build a +name+ prefixed key for the arguments +args+.
67
+ #
68
+ # The argument list is +Marshal#+d so structurally-identical arguments
69
+ # always collide on the same key regardless of object identity.
70
+ #
71
+ # @param name [String, Symbol] The method/function name.
72
+ # @param args [Array] The arguments to key on (positional, then splatted
73
+ # keywords).
74
+ # @return [String] The full cache key.
42
75
  def build_key(name, *args)
43
76
  "#{build_key_prefix(name)}/#{Marshal.dump(args)}"
44
77
  end
45
78
 
46
79
  # Apply the visibility of method +id+ to the wrapper method of this method.
80
+ #
81
+ # The block is expected to (re)define +id+ as +public+; afterwards the
82
+ # original visibility is re-applied in the +ensure+ clause so a memoized
83
+ # +private+ method stays +private+.
84
+ #
85
+ # @param id [String, Symbol] The name of the method whose visibility to
86
+ # mirror.
87
+ # @yield The block that performs the +define_method+ of +id+.
47
88
  def memoize_apply_visibility(id)
48
89
  visibility = instance_eval do
49
90
  case
@@ -1,2 +1,21 @@
1
+ # Marker interface for Mize-compatible cache backends.
2
+ #
3
+ # A cache backend "is a" +Mize::CacheProtocol+ simply by including this
4
+ # module. No methods are mandated — the module exists solely as a type tag
5
+ # that Mize can match against.
6
+ #
7
+ # The primary consumer is +Mize.cache_clear+ (see +Mize::GlobalClear+), which
8
+ # walks the heap with +ObjectSpace.each_object(Mize::CacheProtocol)+ to locate
9
+ # every live cache instance and clear it. This is what turns a per-object
10
+ # cache into a globally clearable one without an explicit registry.
11
+ #
12
+ # @example A minimal compliant backend
13
+ # class MyCache
14
+ # include Mize::CacheProtocol
15
+ #
16
+ # def read(name, options = nil) ... end
17
+ # def write(name, value, options = nil) ... end
18
+ # def clear(options = nil) ... end
19
+ # end
1
20
  module Mize::CacheProtocol
2
21
  end
@@ -1,13 +1,40 @@
1
+ # Configuration helpers mixed in / extended onto the top-level +Mize+ object.
2
+ #
3
+ # Provides the block-based +Mize.configure+ DSL and the +default_cache+
4
+ # accessor so users can swap the global cache backend.
1
5
  module Mize::Configure
6
+ # The global default cache backend.
7
+ #
8
+ # Every memoized object that has not been given an explicit cache
9
+ # instantiates a fresh copy (via +prototype+ / "dup") of this backend.
10
+ # Reassign it to route all new memoized calls through a different store
11
+ # (Redis, Memcached, ...).
12
+ #
13
+ # @return [Mize::CacheProtocol] The current global default cache backend.
2
14
  attr_accessor :default_cache
3
15
 
4
16
  # Set the default cache object to +cache+.
17
+ #
18
+ # Intended for use inside a +Mize.configure {}+ block.
19
+ #
20
+ # @param cache [Mize::CacheProtocol] The backend to install as the default.
21
+ # @return [Mize::CacheProtocol] The backend now installed.
5
22
  def cache(cache)
6
23
  self.default_cache = cache
7
24
  end
8
25
 
9
- # Configures Mize by executing a block of code and executing it in
10
- # configuration context/passing the configuration into it.
26
+ # Configure Mize by evaluating +block+ in the context of the +Mize+ object.
27
+ #
28
+ # Inside the block, +cache+ (and the +default_cache+ accessor) are called
29
+ # directly on +Mize+, so no receiver is required.
30
+ #
31
+ # @example
32
+ # Mize.configure do
33
+ # cache MyRedisCache.new
34
+ # end
35
+ #
36
+ # @yield The configuration block, evaluated via +instance_eval+.
37
+ # @return [Object] The return value of +block+.
11
38
  def configure(&block)
12
39
  instance_eval(&block)
13
40
  end
@@ -17,4 +44,5 @@ module Mize
17
44
  extend Mize::Configure
18
45
  end
19
46
 
47
+ # Install the built-in in-memory backend as the global default.
20
48
  Mize.default_cache = Mize::DefaultCache.new
@@ -1,14 +1,30 @@
1
- require 'monitor'
2
-
1
+ # The default in-memory cache backend.
2
+ #
3
+ # A plain +Hash+ wrapper that implements just enough of the Mize cache
4
+ # protocol to back memoization out of the box: +read+ / +write+ /
5
+ # +exist?+ / +delete+ / +clear+ / +each_name+.
6
+ #
7
+ # Individual operations are atomic under the GVL. For multi-step
8
+ # atomicity (e.g. check→compute→write), wrap the call in
9
+ # +Mize.synchronize+.
10
+ #
11
+ # Because it is backed by a plain +Hash+, entries are never evicted until you
12
+ # clear the cache explicitly (or the object is garbage-collected). For
13
+ # persistent or evicting behaviour, swap in a different
14
+ # +Mize::CacheProtocol+ implementation via +Mize.configure+.
3
15
  class Mize::DefaultCache
4
16
  include Mize::CacheProtocol
5
- include MonitorMixin
6
17
 
18
+ # Create an empty cache.
19
+ #
20
+ # @return [Mize::DefaultCache] A new, empty cache instance.
7
21
  def initialize
8
22
  @data = {}
9
23
  end
10
24
 
11
- # Clear the cache by removing all entries from the cache
25
+ # Clear the cache by removing all entries from the cache.
26
+ #
27
+ # @return [self] The receiver, for chaining.
12
28
  def clear(options = nil)
13
29
  @data.clear
14
30
  self
@@ -17,16 +33,18 @@ class Mize::DefaultCache
17
33
  # Determine whether a cache entry exists in this cache.
18
34
  #
19
35
  # @param name [String] The name of the cache entry to check.
36
+ # @param options [Hash, nil] Optional backend-specific options (ignored).
20
37
  # @return [Boolean] Whether or not the cache entry exists.
21
38
  def exist?(name, options = nil)
22
39
  @data.key?(name)
23
40
  end
24
41
 
25
42
  # Read a value from the cache by name. If the entry does not exist in the
26
- # cache, it will return nil.
43
+ # cache, it will return +nil+.
27
44
  #
28
45
  # @param name [String] The name of the cache entry to read.
29
- # @return [Object] The value stored in the cache for the given name.
46
+ # @param options [Hash, nil] Optional backend-specific options (ignored).
47
+ # @return [Object, nil] The value stored in the cache for +name+, or +nil+.
30
48
  def read(name, options = nil)
31
49
  @data.fetch(name, nil)
32
50
  end
@@ -35,34 +53,49 @@ class Mize::DefaultCache
35
53
  # exists in the cache, it will be overwritten.
36
54
  #
37
55
  # @param name [String] The name of the cache entry to write.
38
- # @param value [Object] The value to store in the cache for the given name.
39
- # @return [Object] The value stored in the chache.
56
+ # @param value [Object] The value to store in the cache for +name+.
57
+ # @param options [Hash, nil] Optional backend-specific options (ignored).
58
+ # @return [Object] The value now stored in the cache.
40
59
  def write(name, value, options = nil)
41
60
  @data.store(name, value)
42
61
  end
43
62
 
44
- # Delete a cache entry by name. If the entry does not exist in the cache, it
63
+ # Delete a cache entry by name. If an entry does not exist in the cache, it
45
64
  # will do nothing.
46
65
  #
47
66
  # @param name [String] The name of the cache entry to delete.
48
- # @return [Object] The value stored in the chache before deletion.
67
+ # @param options [Hash, nil] Optional backend-specific options (ignored).
68
+ # @return [Object, nil] The value stored in the cache before deletion, or
69
+ # +nil+ if the entry was absent.
49
70
  def delete(name, options = nil)
50
71
  @data.delete(name)
51
72
  end
52
73
 
53
74
  # Each name of the cache is yielded to the block.
54
- # @return [self]
75
+ #
76
+ # @yieldparam name [String] Each cache entry name, in turn.
77
+ # @return [self] The receiver, for chaining.
55
78
  def each_name(&block)
56
79
  @data.each_key(&block)
57
80
  self
58
81
  end
59
82
 
60
83
  # Initialize a duplicate of this cache.
61
- # @param other [Mize::DefaultCache] The other cache to initialize a duplicate of.
84
+ #
85
+ # The underlying store is shallow-copied so the original and the duplicate
86
+ # diverge immediately (this is what +prototype+ relies on to hand each
87
+ # memoized object its own independent cache).
88
+ #
89
+ # @param other [Mize::DefaultCache] The cache to initialize a duplicate of.
90
+ # @return [Mize::DefaultCache] +self+, now a copy of +other+.
62
91
  def initialize_dup(other)
63
92
  super
64
93
  other.instance_variable_set :@data, @data.dup
65
94
  end
66
95
 
96
+ # Create a shallow copy of this cache; the public name for +dup+.
97
+ #
98
+ # @return [Mize::DefaultCache] A new cache with an independent copy of the
99
+ # entries.
67
100
  alias prototype dup
68
101
  end
@@ -2,14 +2,28 @@ module Mize
2
2
  class << self
3
3
 
4
4
  # Clear all memoization caches at once.
5
+ #
6
+ # Walks every live +Mize::CacheProtocol+ instance in the process (see
7
+ # +each_cache+) and invokes +clear+ on each, inside +Mize.synchronize+ so
8
+ # the sweep is atomic with respect to concurrent reads/writes.
9
+ #
10
+ # @return [Mize] The +Mize+ module itself.
5
11
  def cache_clear
6
12
  each_cache(&:clear)
7
13
  end
8
14
 
9
15
  private
10
16
 
17
+ # Yield every live +Mize::CacheProtocol+ object to the block.
18
+ #
19
+ # The sweep runs under +Mize.synchronize+ so it cannot observe a
20
+ # half-cleared cache. Objects only appear here because they
21
+ # +include Mize::CacheProtocol+.
22
+ #
23
+ # @yield [cache] Yields each live cache backend in turn.
24
+ # @return [Mize] The +Mize+ module itself.
11
25
  def each_cache
12
- Mize::MUTEX.synchronize do
26
+ Mize.synchronize do
13
27
  for cache in ObjectSpace.each_object(Mize::CacheProtocol)
14
28
  yield cache
15
29
  end
data/lib/mize/memoize.rb CHANGED
@@ -2,18 +2,43 @@ require 'mize/cache_methods'
2
2
  require 'mize/reload'
3
3
 
4
4
  module Mize
5
+ # Memoization entry point, prepended into every +::Module+ by +mize.rb+.
6
+ #
7
+ # Including this module (or relying on the global +prepend+) exposes
8
+ # +memoize+, +mize_cache_clear+ and +mize_cache_clear_name+ on the
9
+ # receiver. The heavy lifting is delegated to +Mize::CacheMethods+ for
10
+ # key/state management and +Mize::Reload+ for cache invalidation.
5
11
  module Memoize
6
12
  include CacheMethods
7
13
 
8
- # Memoize either a +method+ or a +function+. In the former case the
9
- # memoized results do NOT ONLY depend on the arguments, but ALSO on the
10
- # object the method is called on. In the latter the memoized results ONLY
11
- # depend on the arguments given to the function. If the +freeze+ argument
12
- # is true, the result is frozen if possible to make it immutable. If the
13
- # store_nil argument is false do not store nil results and always recompute
14
- # otherwise don't which is the default.
14
+ # Memoize either a +method+ or a +function+.
15
+ #
16
+ # In the +method+ case the memoized results do NOT ONLY depend on the
17
+ # arguments, but ALSO on the object the method is called on (each object
18
+ # keeps its own cache). In the +function+ case the memoized results ONLY
19
+ # depend on the arguments, and a single shared cache backs every call.
20
+ #
21
+ # You must specify exactly one of +method:+ or +function:+; passing both
22
+ # or neither raises +ArgumentError+.
23
+ #
24
+ # @param method [String, Symbol, nil] The instance method to wrap.
25
+ # @param function [String, Symbol, nil] The bare/stateless function to wrap.
26
+ # @param freeze [true, false] When true, successfully computed results are
27
+ # frozen (if they respond to +freeze+) to make them immutable.
28
+ # @param store_nil [true, false] When false, +nil+ results are not stored
29
+ # and are recomputed every call; defaults to +true+ (store +nil+).
30
+ # @raise [ArgumentError] If both or neither of +method:+/+function:+ are
31
+ # given.
32
+ # @return [Symbol] The (stringified) symbol of the wrapped method id.
33
+ # @example Memoizing an instance method
34
+ # class Foo
35
+ # include Mize::Memoize
36
+ #
37
+ # def expensive(x) x * 2 end
38
+ # memoize method: :expensive, freeze: true
39
+ # end
15
40
  def memoize(method: nil, function: nil, freeze: false, store_nil: true)
16
- Mize::MUTEX.synchronize do
41
+ Mize.synchronize do
17
42
  if method && function
18
43
  raise ArgumentError, 'memoize a method xor a function'
19
44
  elsif method
@@ -31,6 +56,19 @@ module Mize
31
56
  class << self
32
57
  private
33
58
 
59
+ # Compute the real result of a memoized call.
60
+ #
61
+ # Binds +orig_method+ to +context+ and invokes it with +args+; when
62
+ # running under +$DEBUG+ a diagnostic line is emitted to +STDERR+.
63
+ #
64
+ # @param method_id [Symbol] The wrapped method name (diagnostics only).
65
+ # @param orig_method [UnboundMethod] The original, unwrapped method.
66
+ # @param key [String] The cache key for this call (diagnostics only).
67
+ # @param context [Object] The object the method is bound to.
68
+ # @param args [Array] The positional arguments.
69
+ # @param kargs [Hash] The keyword arguments.
70
+ # @param freeze [true, false] Whether to freeze the resulting value.
71
+ # @return [Object] The (possibly frozen) computed result.
34
72
  def compute_result(method_id, orig_method, key, context, args, kargs, freeze)
35
73
  result = orig_method.bind(context).call(*args)
36
74
  if $DEBUG
@@ -43,7 +81,25 @@ module Mize
43
81
  end
44
82
  end
45
83
 
46
- def wrap_method(method_id, freeze: false, function: false, store_nil: true)
84
+ # Wrap +method_id+ with a memoizing closure.
85
+ #
86
+ # Idempotency: a +[self, method_id, function]+ target already present in
87
+ # +Mize.wrapped+ with identical +freeze+ / +store_nil+ options is a
88
+ # no-op; conflicting options raise +ArgumentError+.
89
+ #
90
+ # For instance methods (+function: false+) the receiver gets its own
91
+ # per-object cache via +Mize::CacheMethods+ and +Mize::Reload+ is
92
+ # prepended so +reload+ invalidates entries. For bare functions a single
93
+ # shared cache is used instead.
94
+ #
95
+ # @param method_id [String, Symbol] The name of the method to wrap.
96
+ # @param freeze [true, false] Forwarded to the wrapper's result handling.
97
+ # @param function [true, false] Whether +method_id+ is a bare function.
98
+ # @param store_nil [true, false] Whether +nil+ results should be cached.
99
+ # @raise [ArgumentError] If the target is already wrapped with different
100
+ # +freeze+ / +store_nil+ options.
101
+ # @return [Symbol] The stringified symbol of the wrapped method id.
102
+ def wrap_method(method_id, freeze: false, function: false, store_nil: true)
47
103
  verbose, $VERBOSE = $VERBOSE, nil
48
104
  if already_wrapped = Mize.wrapped[ [ self, method_id, function ] ]
49
105
  if already_wrapped == [ freeze, store_nil ]
data/lib/mize/railtie.rb CHANGED
@@ -1,4 +1,11 @@
1
1
  module Mize
2
+ # Rails integration.
3
+ #
4
+ # Hooks into the Rails preparation lifecycle so that every code reload
5
+ # clears all Mize caches via +Mize.cache_clear+, preventing stale memoized
6
+ # results from surviving a development-environment class reload.
7
+ #
8
+ # Loaded automatically by +mize.rb+ only when +Rails+ is defined.
2
9
  class Railtie < Rails::Railtie
3
10
  config.to_prepare do
4
11
  Mize.cache_clear
data/lib/mize/reload.rb CHANGED
@@ -1,8 +1,21 @@
1
+ # Reload/invalidation hook, prepended into any module that memoizes an
2
+ # instance method.
3
+ #
4
+ # When a class defines (or inherits) its own +reload+, Mize wraps it so the
5
+ # cache is guaranteed to be cleared alongside whatever the user's +reload+
6
+ # does, keeping memoized state consistent after a full object reload.
1
7
  module Mize::Reload
2
- # Reload this object if a #reload method was provided up somewhere in the
3
- # inheritance tree, afterwards clear the memoization cache and return self.
8
+ # Run the parent +reload+ (if any), then clear Mize's bookkeeping and the
9
+ # object's memoization cache.
10
+ #
11
+ # The whole sequence is serialized on +Mize.synchronize+. +Mize.wrapped+ is
12
+ # reset so a re-memoization with different options is allowed, and
13
+ # +mize_cache_clear+ drops every cached value for this object.
14
+ #
15
+ # @return [Object] The result of the parent +reload+ if one was defined,
16
+ # otherwise +self+.
4
17
  def reload(*)
5
- Mize::MUTEX.synchronize do
18
+ Mize.synchronize do
6
19
  result = self
7
20
  if defined? super
8
21
  result = super
data/lib/mize/version.rb CHANGED
@@ -1,6 +1,11 @@
1
+ # Version information for the Mize gem.
2
+ #
3
+ # This module is auto-generated by GemHadar and exposes the
4
+ # current release version as a set of constants. Do not edit it
5
+ # by hand; it is rewritten on every `rake version` invocation.
1
6
  module Mize
2
- # Mize version
3
- VERSION = '0.6.1'
7
+ # The current version of the Mize gem as a String.
8
+ VERSION = '0.7.0'
4
9
  VERSION_ARRAY = VERSION.split('.').map(&:to_i) # :nodoc:
5
10
  VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
6
11
  VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
data/lib/mize.rb CHANGED
@@ -1,10 +1,71 @@
1
1
  require 'thread'
2
2
 
3
+ # Mize — a minimal, dependency-free memoization toolkit for Ruby.
4
+ #
5
+ # Mize lets you wrap any method (or a bare, stateless "function") so that its
6
+ # result is cached and reused for identical arguments. It ships with an
7
+ # in-memory +Mize::DefaultCache+ but accepts any object that includes
8
+ # +Mize::CacheProtocol+, so you can plug in Redis, Memcached, and friends.
9
+ #
10
+ # @example Wrapping a method
11
+ # class Greeter
12
+ # include Mize::Memoize
13
+ #
14
+ # def expensive(name)
15
+ # # ...
16
+ # end
17
+ # memoize method: :expensive
18
+ # end
3
19
  module Mize
20
+ # Process-wide lock guarding all cache and wrapping mutations.
21
+ #
22
+ # Every operation that mutates shared Mize state (+memoize+,
23
+ # +Mize.cache_clear+, +Mize::Reload#reload+) serialises on this mutex, so
24
+ # the toolkit is safe to use from multiple threads.
4
25
  MUTEX = Mutex.new
5
26
 
6
27
  class << self
28
+ # Bookkeeping of already-wrapped targets.
29
+ #
30
+ # Maps +[module, method_id, function]+ => +[freeze, store_nil]+ so that
31
+ # duplicate +memoize+ calls can be detected and conflicting options
32
+ # rejected. Cleared on +Mize::Reload#reload+.
7
33
  attr_accessor :wrapped
34
+
35
+ # Acquire the global Mize mutex for the duration of +block+.
36
+ #
37
+ # Exposes the internal +MUTEX+ under a stable API so callers can make
38
+ # a sequence of memoized calls atomic with respect to other threads:
39
+ #
40
+ # @example
41
+ # Mize.synchronize do
42
+ # obj.foo(42)
43
+ # obj.bar(42)
44
+ # end
45
+ #
46
+ # The hot path (individual memoized calls) is lock-free by design; use
47
+ # this when you need the check→compute→write cycle to be indivisible.
48
+ #
49
+ # MRI forbids +Mutex#synchronize+ from a trap context (signal handlers
50
+ # and GC finalizers), raising +ThreadError: can't be called from trap
51
+ # context+. This is an intentional, still-current design decision (see
52
+ # DevMeeting-2025-07-10 on
53
+ # https://bugs.ruby-lang.org/issues/19473), not a bug being patched, so
54
+ # this method rescues that specific error and runs +block+ without the
55
+ # lock rather than raising into a finalizer. Other +ThreadError+s (e.g.
56
+ # recursive locking) are re-raised.
57
+ #
58
+ # @yield Executes the block while holding the mutex.
59
+ # @return [Object] The return value of +block+.
60
+ def synchronize(&block)
61
+ MUTEX.synchronize(&block)
62
+ rescue ThreadError => e
63
+ if e.message.include?("trap context")
64
+ block.()
65
+ else
66
+ raise e
67
+ end
68
+ end
8
69
  end
9
70
  self.wrapped = {}
10
71
  end
@@ -15,6 +76,8 @@ require 'mize/configure'
15
76
  require 'mize/global_clear'
16
77
  require 'mize/railtie' if defined? Rails
17
78
 
79
+ # Inject +memoize+ into every module so any class can opt in with a single
80
+ # +include Mize::Memoize+.
18
81
  class ::Module
19
82
  prepend Mize::Memoize
20
83
  end
data/mize.gemspec CHANGED
@@ -1,29 +1,30 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: mize 0.6.1 ruby lib
2
+ # stub: mize 0.7.0 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "mize".freeze
6
- s.version = "0.6.1".freeze
6
+ s.version = "0.7.0".freeze
7
7
 
8
8
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
9
+ s.metadata = { "source_code_uri" => "https://github.com/flori/mize" } if s.respond_to? :metadata=
9
10
  s.require_paths = ["lib".freeze]
10
11
  s.authors = ["Florian Frank".freeze]
11
- s.date = "2024-10-17"
12
- s.description = "Library that provides memoziation for methods and functions for Ruby.".freeze
12
+ s.date = "1980-01-02"
13
+ s.description = "Library that provides memoization for methods and functions for Ruby.".freeze
13
14
  s.email = "flori@ping.de".freeze
14
15
  s.extra_rdoc_files = ["README.md".freeze, "lib/mize.rb".freeze, "lib/mize/cache_methods.rb".freeze, "lib/mize/cache_protocol.rb".freeze, "lib/mize/configure.rb".freeze, "lib/mize/default_cache.rb".freeze, "lib/mize/global_clear.rb".freeze, "lib/mize/memoize.rb".freeze, "lib/mize/railtie.rb".freeze, "lib/mize/reload.rb".freeze, "lib/mize/version.rb".freeze]
15
- s.files = [".all_images.yml".freeze, ".gitignore".freeze, ".rspec".freeze, ".travis.yml".freeze, ".utilsrc".freeze, "CHANGES.md".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "config/broken_config.yml".freeze, "config/config.yml".freeze, "lib/mize.rb".freeze, "lib/mize/cache_methods.rb".freeze, "lib/mize/cache_protocol.rb".freeze, "lib/mize/configure.rb".freeze, "lib/mize/default_cache.rb".freeze, "lib/mize/global_clear.rb".freeze, "lib/mize/memoize.rb".freeze, "lib/mize/railtie.rb".freeze, "lib/mize/reload.rb".freeze, "lib/mize/version.rb".freeze, "mize.gemspec".freeze, "spec/mize/global_clear_spec.rb".freeze, "spec/mize/memoize_method_spec.rb".freeze, "spec/mize/memoize_reload_spec.rb".freeze, "spec/mize/version_spec.rb".freeze, "spec/spec_helper.rb".freeze]
16
+ s.files = [".all_images.yml".freeze, ".github/workflows/static.yml".freeze, ".gitignore".freeze, ".rspec".freeze, ".travis.yml".freeze, "CHANGES.md".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "lib/mize.rb".freeze, "lib/mize/cache_methods.rb".freeze, "lib/mize/cache_protocol.rb".freeze, "lib/mize/configure.rb".freeze, "lib/mize/default_cache.rb".freeze, "lib/mize/global_clear.rb".freeze, "lib/mize/memoize.rb".freeze, "lib/mize/railtie.rb".freeze, "lib/mize/reload.rb".freeze, "lib/mize/version.rb".freeze, "mize.gemspec".freeze, "spec/mize/global_clear_spec.rb".freeze, "spec/mize/memoize_method_spec.rb".freeze, "spec/mize/memoize_reload_spec.rb".freeze, "spec/mize/version_spec.rb".freeze, "spec/mize_spec.rb".freeze, "spec/spec_helper.rb".freeze]
16
17
  s.homepage = "https://github.com/flori/mize".freeze
17
18
  s.licenses = ["MIT".freeze]
18
- s.rdoc_options = ["--title".freeze, "Mize - Library that provides memoziation for methods and functions".freeze, "--main".freeze, "README.md".freeze]
19
+ s.rdoc_options = ["--title".freeze, "Mize - Library that provides memoization for methods and functions".freeze, "--main".freeze, "README.md".freeze]
19
20
  s.required_ruby_version = Gem::Requirement.new(">= 2".freeze)
20
- s.rubygems_version = "3.5.18".freeze
21
- s.summary = "Library that provides memoziation for methods and functions".freeze
22
- s.test_files = ["spec/mize/global_clear_spec.rb".freeze, "spec/mize/memoize_method_spec.rb".freeze, "spec/mize/memoize_reload_spec.rb".freeze, "spec/mize/version_spec.rb".freeze, "spec/spec_helper.rb".freeze]
21
+ s.rubygems_version = "4.0.22".freeze
22
+ s.summary = "Library that provides memoization for methods and functions".freeze
23
+ s.test_files = ["spec/mize/global_clear_spec.rb".freeze, "spec/mize/memoize_method_spec.rb".freeze, "spec/mize/memoize_reload_spec.rb".freeze, "spec/mize/version_spec.rb".freeze, "spec/mize_spec.rb".freeze, "spec/spec_helper.rb".freeze]
23
24
 
24
25
  s.specification_version = 4
25
26
 
26
- s.add_development_dependency(%q<gem_hadar>.freeze, ["~> 1.19".freeze])
27
+ s.add_development_dependency(%q<gem_hadar>.freeze, [">= 2.20.1".freeze])
27
28
  s.add_development_dependency(%q<rake>.freeze, [">= 0".freeze])
28
29
  s.add_development_dependency(%q<simplecov>.freeze, [">= 0".freeze])
29
30
  s.add_development_dependency(%q<rspec>.freeze, [">= 0".freeze])
@@ -1,5 +1,3 @@
1
- require 'spec_helper'
2
-
3
1
  class Foo
4
2
  def self.reset
5
3
  @@foo = nil
@@ -1,5 +1,3 @@
1
- require 'spec_helper'
2
-
3
1
  class FooBar
4
2
  class << self
5
3
  def reset
@@ -1,5 +1,3 @@
1
- require 'spec_helper'
2
-
3
1
  class Foo
4
2
  def self.reset
5
3
  @@foo = nil
@@ -1,5 +1,3 @@
1
- require 'spec_helper'
2
-
3
1
  describe 'Mize::VERSION' do
4
2
  it 'has a version' do
5
3
  expect(Mize::VERSION).to be_a String
data/spec/mize_spec.rb ADDED
@@ -0,0 +1,13 @@
1
+ describe Mize do
2
+ describe '.synchronize' do
3
+ it 'executes the block and returns its value' do
4
+ expect(described_class.synchronize { 42 }).to eq(42)
5
+ end
6
+
7
+ it 'is the same lock object as Mize::MUTEX' do
8
+ expect {
9
+ Mize::MUTEX.synchronize { Mize.synchronize { :x } }
10
+ }.to raise_error(ThreadError)
11
+ end
12
+ end
13
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,8 +1,7 @@
1
- if ENV['START_SIMPLECOV'].to_i == 1
2
- require 'simplecov'
3
- SimpleCov.start do
4
- add_filter "#{File.basename(File.dirname(__FILE__))}/"
5
- end
1
+ begin
2
+ require 'gem_hadar/simplecov'
3
+ GemHadar::SimpleCov.start
4
+ rescue LoadError
6
5
  end
7
6
  require 'rspec'
8
7
  require 'mize'
metadata CHANGED
@@ -1,29 +1,28 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mize
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Frank
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-10-17 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: gem_hadar
15
14
  requirement: !ruby/object:Gem::Requirement
16
15
  requirements:
17
- - - "~>"
16
+ - - ">="
18
17
  - !ruby/object:Gem::Version
19
- version: '1.19'
18
+ version: 2.20.1
20
19
  type: :development
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
- - - "~>"
23
+ - - ">="
25
24
  - !ruby/object:Gem::Version
26
- version: '1.19'
25
+ version: 2.20.1
27
26
  - !ruby/object:Gem::Dependency
28
27
  name: rake
29
28
  requirement: !ruby/object:Gem::Requirement
@@ -108,7 +107,7 @@ dependencies:
108
107
  - - ">="
109
108
  - !ruby/object:Gem::Version
110
109
  version: '0'
111
- description: Library that provides memoziation for methods and functions for Ruby.
110
+ description: Library that provides memoization for methods and functions for Ruby.
112
111
  email: flori@ping.de
113
112
  executables: []
114
113
  extensions: []
@@ -126,18 +125,16 @@ extra_rdoc_files:
126
125
  - lib/mize/version.rb
127
126
  files:
128
127
  - ".all_images.yml"
128
+ - ".github/workflows/static.yml"
129
129
  - ".gitignore"
130
130
  - ".rspec"
131
131
  - ".travis.yml"
132
- - ".utilsrc"
133
132
  - CHANGES.md
134
133
  - Gemfile
135
134
  - LICENSE
136
135
  - README.md
137
136
  - Rakefile
138
137
  - VERSION
139
- - config/broken_config.yml
140
- - config/config.yml
141
138
  - lib/mize.rb
142
139
  - lib/mize/cache_methods.rb
143
140
  - lib/mize/cache_protocol.rb
@@ -153,15 +150,16 @@ files:
153
150
  - spec/mize/memoize_method_spec.rb
154
151
  - spec/mize/memoize_reload_spec.rb
155
152
  - spec/mize/version_spec.rb
153
+ - spec/mize_spec.rb
156
154
  - spec/spec_helper.rb
157
155
  homepage: https://github.com/flori/mize
158
156
  licenses:
159
157
  - MIT
160
- metadata: {}
161
- post_install_message:
158
+ metadata:
159
+ source_code_uri: https://github.com/flori/mize
162
160
  rdoc_options:
163
161
  - "--title"
164
- - Mize - Library that provides memoziation for methods and functions
162
+ - Mize - Library that provides memoization for methods and functions
165
163
  - "--main"
166
164
  - README.md
167
165
  require_paths:
@@ -177,13 +175,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
177
175
  - !ruby/object:Gem::Version
178
176
  version: '0'
179
177
  requirements: []
180
- rubygems_version: 3.5.18
181
- signing_key:
178
+ rubygems_version: 4.0.22
182
179
  specification_version: 4
183
- summary: Library that provides memoziation for methods and functions
180
+ summary: Library that provides memoization for methods and functions
184
181
  test_files:
185
182
  - spec/mize/global_clear_spec.rb
186
183
  - spec/mize/memoize_method_spec.rb
187
184
  - spec/mize/memoize_reload_spec.rb
188
185
  - spec/mize/version_spec.rb
186
+ - spec/mize_spec.rb
189
187
  - spec/spec_helper.rb
data/.utilsrc DELETED
@@ -1,26 +0,0 @@
1
- # vim: set ft=ruby:
2
-
3
- search do
4
- prune_dirs /\A(\.svn|\.git|CVS|tmp|tags|coverage|doc|pkg)\z/
5
- skip_files /(\A\.|\.sw[pon]\z|\.(log|fnm|jpg|jpeg|png|pdf|svg)\z|tags|~\z)/i
6
- end
7
-
8
- discover do
9
- prune_dirs /\A(\.svn|\.git|CVS|tmp|tags|coverage|doc|pkg)\z/
10
- skip_files /(\A\.|\.sw[pon]\z|\.log\z|~\z)/
11
- binary false
12
- end
13
-
14
- strip_spaces do
15
- prune_dirs /\A(\..*|CVS|pkg)\z/
16
- skip_files /(\A\.|\.sw[pon]\z|\.log\z|~\z)/
17
- end
18
-
19
- probe do
20
- test_framework :rspec
21
- #include_dirs 'features'
22
- end
23
-
24
- ssh_tunnel do
25
- terminal_multiplexer :tmux
26
- end
@@ -1 +0,0 @@
1
- ,kaput
data/config/config.yml DELETED
@@ -1,13 +0,0 @@
1
- development:
2
- config:
3
- foo: true
4
- bar: false
5
- baz: 'something'
6
- pi: <%= Math::PI %>
7
-
8
- test:
9
- config:
10
- foo: false
11
- bar: true
12
- baz: 'something else'
13
- pi: 3.141