From 95590b70dc71e640b825918b44b8e0b38181e69f Mon Sep 17 00:00:00 2001 From: HParker Date: Tue, 5 Jan 2021 11:24:52 -0800 Subject: [PATCH] Allow ostruct to return a value on super This fixes cases where you can super in something that inherits from OpenStruct ``` require 'ostruct' class Foo < OpenStruct def foo super end end p Foo.new(foo: 123).foo ``` Previously: => nil Now: => 123 Co-authored-by: John Hawthorn Test OpenStruct super works --- lib/ostruct.rb | 6 +++++- test/ostruct/test_ostruct.rb | 8 ++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/ostruct.rb b/lib/ostruct.rb index a5a5140d10..7a6e427c39 100644 --- a/lib/ostruct.rb +++ b/lib/ostruct.rb @@ -239,7 +239,11 @@ def freeze raise! ArgumentError, "wrong number of arguments (given #{len}, expected 1)", caller(1) end set_ostruct_member_value!(mname, args[0]) - elsif len == 0 + elsif len == 0 # and /\A[a-z_]\w*\z/ =~ mid # + if @table.key?(mid) + new_ostruct_member!(mid) unless frozen? + @table[mid] + end else begin super diff --git a/test/ostruct/test_ostruct.rb b/test/ostruct/test_ostruct.rb index 3ca98ee739..443a20c86a 100644 --- a/test/ostruct/test_ostruct.rb +++ b/test/ostruct/test_ostruct.rb @@ -249,6 +249,14 @@ def test_overridden_private_methods assert_equal(:bar, os.format) end + def test_super + c = Class.new(OpenStruct) { + def foo; super; end + } + os = c.new(foo: :bar) + assert_equal(:bar, os.foo) + end + def test_overridden_public_methods os = OpenStruct.new(method: :foo, class: :bar) assert_equal(:foo, os.method) -- 2.28.0