Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

## [Unreleased](https://github.com/panorama-ed/memo_wise/compare/v1.13.0...HEAD)

**Gem enhancements:** none
**Gem enhancements:**

- Allow using `MemoWise` in subclasses of classes that have `prepend MemoWise` [[#392]](https://github.com/panorama-ed/memo_wise/pull/392)

_No breaking changes!_

Expand Down
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,17 +116,17 @@ Benchmarks are run in GitHub Actions, and the tables below are updated with ever

Results using Ruby 3.4.3:

|Method arguments|`alt_memery` (2.1.0)|`dry-core`\* (1.1.0)|`memery` (1.7.0)|`memoist3` (1.0.0)|`short_circu_it` (0.29.3)|

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Method arguments memo_wise-github-main (1.13.0)
() (none) 1.00x
(a) 1.00x
(a, b) 0.98x
(a:) 0.99x
(a:, b:) 1.01x
(a, b:) 1.00x
(a, *args) 1.05x
(a:, **kwargs) 0.97x
(a, *args, b:, **kwargs) 1.00x

|Method arguments|`alt_memery` (2.1.0)|`dry-core` (1.1.0)|`memery` (1.7.0)|`memoist3` (1.0.0)|`short_circu_it` (0.29.3)|
|--|--|--|--|--|--|
|`()` (none)|12.20x|0.57x|3.31x|2.76x|18.45x|
|`(a)`|9.75x|0.98x|3.76x|14.54x|13.96x|
|`(a, b)`|7.59x|0.82x|2.92x|11.39x|10.87x|
|`(a:)`|14.89x|0.97x|6.39x|19.76x|12.60x|
|`(a:, b:)`|12.64x|0.86x|5.43x|21.05x|10.70x|
|`(a, b:)`|12.25x|0.84x|5.22x|16.12x|10.31x|
|`(a, *args)`|1.89x|0.65x|0.73x|2.84x|2.70x|
|`(a:, **kwargs)`|2.86x|0.71x|1.21x|4.79x|2.42x|
|`(a, *args, b:, **kwargs)`|1.81x|0.62x|0.83x|3.03x|1.52x|
|`()` (none)|15.07x|0.65x|8.09x|6.68x|17.71x|
|`(a)`|7.75x|1.00x|5.74x|15.19x|10.51x|
|`(a, b)`|6.32x|0.87x|4.61x|12.51x|8.63x|
|`(a:)`|10.89x|1.01x|6.83x|20.19x|9.97x|
|`(a:, b:)`|8.99x|0.88x|5.63x|21.51x|8.29x|
|`(a, b:)`|8.80x|0.87x|5.52x|16.51x|8.18x|
|`(a, *args)`|2.14x|0.87x|1.41x|4.10x|2.73x|
|`(a:, **kwargs)`|2.73x|0.75x|2.45x|7.68x|3.19x|
|`(a, *args, b:, **kwargs)`|1.77x|0.73x|1.12x|4.38x|1.66x|

\* `dry-core`
[may cause incorrect behavior caused by hash collisions](https://github.com/dry-rb/dry-core/issues/63).
Expand Down
7 changes: 7 additions & 0 deletions lib/memo_wise.rb
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,13 @@ def allocate
MemoWise::InternalAPI.create_memo_wise_state!(super)
end

# [`Class#inherited`](https://ruby-doc.org/3.3.1/Class.html#method-i-inherited) is used here
# to make MemoWise methods available in subclasses.
def inherited(subclass)
super
subclass.prepend(MemoWise)
end

# NOTE: See YARD docs for {.memo_wise} directly below this method!
def memo_wise(method_name_or_hash)
klass = self
Expand Down
1 change: 1 addition & 0 deletions spec/adding_methods_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
memo_wise
preset_memo_wise
reset_memo_wise
inherited
].to_set
end

Expand Down
8 changes: 8 additions & 0 deletions spec/memo_wise_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,14 @@ def module1_method
end
end

context "when a class inherits from a parent class where memo_wise is defined" do
include_context "with context for inherited class instance"

let(:target) { instance }

it_behaves_like "#memo_wise shared examples"
end

context "with module mixed into other classes" do
context "when extended" do
context "when defined with 'def'" do
Expand Down
1 change: 1 addition & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
require "support/shared_context_for_instance_methods"
require "support/shared_context_for_class_methods_via_self_dot"
require "support/shared_context_for_class_methods_via_class_scope"
require "support/shared_context_for_inherited_class_instance"
require "support/shared_context_for_module_methods_via_self_dot"
require "support/shared_context_for_module_methods_via_class_scope"
require "support/shared_context_for_module_methods_via_normal_scope"
22 changes: 22 additions & 0 deletions spec/support/shared_context_for_inherited_class_instance.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# frozen_string_literal: true

RSpec.shared_context "with context for inherited class instance" do
let(:parent_class) do
Class.new do
prepend MemoWise
end
end

let(:inherited_class_with_memo) do
Class.new(parent_class) do
def initialize; end

DefineMethodsForTestingMemoWise.define_methods_for_testing_memo_wise(
target: self,
via: :instance
)
end
end

let(:instance) { inherited_class_with_memo.new }
end