From bc930abce00dabc931d0766a33f7b1db38f6d578 Mon Sep 17 00:00:00 2001 From: Frances McMullin Date: Wed, 16 Oct 2024 16:28:55 +0100 Subject: [PATCH 1/2] Avoid error when member is present on ancestor class Niche case - when clearing class members for new definition, avoid trying to remove members present on ancestor classes. --- .../concurrent/synchronization/abstract_struct.rb | 2 +- spec/concurrent/struct_shared.rb | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/concurrent-ruby/concurrent/synchronization/abstract_struct.rb b/lib/concurrent-ruby/concurrent/synchronization/abstract_struct.rb index 1fe90c164..28816c518 100644 --- a/lib/concurrent-ruby/concurrent/synchronization/abstract_struct.rb +++ b/lib/concurrent-ruby/concurrent/synchronization/abstract_struct.rb @@ -157,7 +157,7 @@ def ns_initialize(*values) end end members.each_with_index do |member, index| - clazz.send :remove_method, member if clazz.instance_methods.include? member + clazz.send :remove_method, member if clazz.instance_methods(false).include? member clazz.send(:define_method, member) do @values[index] end diff --git a/spec/concurrent/struct_shared.rb b/spec/concurrent/struct_shared.rb index ae812f223..6dd91870d 100644 --- a/spec/concurrent/struct_shared.rb +++ b/spec/concurrent/struct_shared.rb @@ -26,6 +26,18 @@ expect(clazz.ancestors).to include described_class end + it 'ignores methods on ancestor classes' do + ancestor = described_class.ancestors.first + ancestor.class_eval { def foo; end } + + clazz = described_class.new(:foo) + expect{ described_class.const_get(clazz.to_s) }.to raise_error(NameError) + expect(clazz).to be_a Class + expect(clazz.ancestors).to include described_class + + ancestor.send :remove_method, :foo + end + it 'raises an exception when given an invalid class name' do expect{ described_class.new('lowercase') }.to raise_error(NameError) expect{ described_class.new('_') }.to raise_error(NameError) From 3a775c49410f1c62d0467b1139606d5b0e27fa07 Mon Sep 17 00:00:00 2001 From: Frances McMullin Date: Wed, 16 Oct 2024 21:08:21 +0100 Subject: [PATCH 2/2] Improve ancestor classes spec --- spec/concurrent/struct_shared.rb | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/spec/concurrent/struct_shared.rb b/spec/concurrent/struct_shared.rb index 6dd91870d..4c73a9e40 100644 --- a/spec/concurrent/struct_shared.rb +++ b/spec/concurrent/struct_shared.rb @@ -27,13 +27,15 @@ end it 'ignores methods on ancestor classes' do - ancestor = described_class.ancestors.first - ancestor.class_eval { def foo; end } + ancestor = described_class.ancestors.last + ancestor.class_eval { def foo(bar); end } clazz = described_class.new(:foo) - expect{ described_class.const_get(clazz.to_s) }.to raise_error(NameError) - expect(clazz).to be_a Class - expect(clazz.ancestors).to include described_class + struct = clazz.new + + expect(struct).to respond_to :foo + method = struct.method(:foo) + expect(method.arity).to eq 0 ancestor.send :remove_method, :foo end