Skip to content

Commit 106a965

Browse files
andrykonchineregon
authored andcommitted
[GR-18163] Fix Struct setters to raise FrozenError when a struct is frozen
PullRequest: truffleruby/4538
2 parents b5b8ed6 + 81615bf commit 106a965

File tree

4 files changed

+19
-1
lines changed

4 files changed

+19
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Compatibility:
2323
* Fix `Kernel#raise` and don't override `cause` at exception re-raising (#3831, @andrykonchin).
2424
* Return a pointer with `#type_size` of 1 for `Pointer#read_pointer` (@eregon).
2525
* Fix `rb_str_locktmp()` and `rb_str_unlocktmp()` to raise `FrozenError` when string argument is frozen (#3752, @andrykonchin).
26+
* Fix Struct setters to raise `FrozenError` when a struct is frozen (#3850, @andrykonchin).
2627

2728
Performance:
2829

spec/ruby/core/struct/element_set_spec.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,11 @@
2626
-> { car[-4] = true }.should raise_error(IndexError)
2727
-> { car[Object.new] = true }.should raise_error(TypeError)
2828
end
29+
30+
it "raises a FrozenError on a frozen struct" do
31+
car = StructClasses::Car.new('Ford', 'Ranger')
32+
car.freeze
33+
34+
-> { car[:model] = 'Escape' }.should raise_error(FrozenError)
35+
end
2936
end

spec/ruby/core/struct/struct_spec.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@
3333
car['model'].should == 'F150'
3434
car[1].should == 'F150'
3535
end
36+
37+
it "writer methods raise a FrozenError on a frozen struct" do
38+
car = StructClasses::Car.new('Ford', 'Ranger')
39+
car.freeze
40+
41+
-> { car.model = 'Escape' }.should raise_error(FrozenError)
42+
end
3643
end
3744

3845
describe "Struct subclasses" do

src/main/ruby/truffleruby/core/struct.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,10 @@ def self.new(*attrs, keyword_init: nil, &block)
5858

5959
attrs.each do |a|
6060
define_method(a) { Primitive.object_hidden_var_get(self, a) }
61-
define_method(:"#{a}=") { |value| Primitive.object_hidden_var_set(self, a, value) }
61+
define_method(:"#{a}=") do |value|
62+
Primitive.check_frozen self
63+
Primitive.object_hidden_var_set(self, a, value)
64+
end
6265
end
6366

6467
def self.new(...)

0 commit comments

Comments
 (0)