From 9cc08e1201c29b4addbe65cab87e5989caaa1ea5 Mon Sep 17 00:00:00 2001 From: Mitsuru Hayasaka Date: Mon, 30 May 2022 22:25:20 +0900 Subject: [PATCH 1/3] Provide pattern matching for OpenStruct --- lib/ostruct.rb | 29 +++++++++++++++++++++++++++++ test/ostruct/test_ostruct.rb | 10 ++++++++++ 2 files changed, 39 insertions(+) diff --git a/lib/ostruct.rb b/lib/ostruct.rb index a08561d..528ee9c 100644 --- a/lib/ostruct.rb +++ b/lib/ostruct.rb @@ -428,6 +428,35 @@ def hash # :nodoc: @table.hash end + # + # Returns a hash of attributes for the given keys. Provides the pattern + # matching interface for matching against hash patterns. For example: + # + # require "ostruct" + # + # def greeting_for(person) + # case person + # in { name: "Mary" } + # "Welcome back, Mary!" + # in { name: } + # "Welcome stranger!" + # end + # end + # + # person = OpenStruct.new(name: "Mary") + # greeting_for(person) # => "Welcome back, Mary!" + # + # person = OpenStruct.new + # greeting_for(person) # => "Welcome stranger!" + # + def deconstruct_keys(keys) + deconstructed = {} + keys.each do |key| + deconstructed[key] = send(key) + end + deconstructed + end + # # Provides marshalling support for use by the YAML library. # diff --git a/test/ostruct/test_ostruct.rb b/test/ostruct/test_ostruct.rb index 256db7a..ec14eb9 100644 --- a/test/ostruct/test_ostruct.rb +++ b/test/ostruct/test_ostruct.rb @@ -412,4 +412,14 @@ def test_class assert_equal('my-class', os.class) assert_equal(OpenStruct, os.class!) end + + def test_pattern_matching + os = OpenStruct.new(class: 'my-class', method: 'post') + case os + in { class: 'my-class', method: 'post' } + assert true + else + assert false + end + end end From a04c6e4ee5db429bce632966145a83c1eea55ee1 Mon Sep 17 00:00:00 2001 From: Mitsuru Hayasaka Date: Tue, 31 May 2022 01:13:00 +0900 Subject: [PATCH 2/3] Use public_send --- lib/ostruct.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ostruct.rb b/lib/ostruct.rb index 528ee9c..99f7dc1 100644 --- a/lib/ostruct.rb +++ b/lib/ostruct.rb @@ -452,7 +452,7 @@ def hash # :nodoc: def deconstruct_keys(keys) deconstructed = {} keys.each do |key| - deconstructed[key] = send(key) + deconstructed[key] = public_send(key) end deconstructed end From 54dbd1df9f9c8756f90f6cb147795834cdefcc3a Mon Sep 17 00:00:00 2001 From: Mitsuru Hayasaka Date: Tue, 31 May 2022 01:22:57 +0900 Subject: [PATCH 3/3] Ignore test_pattern_matching if RUBY_VERSION <= 2.6 --- test/ostruct/test_ostruct.rb | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/test/ostruct/test_ostruct.rb b/test/ostruct/test_ostruct.rb index ec14eb9..177c9d0 100644 --- a/test/ostruct/test_ostruct.rb +++ b/test/ostruct/test_ostruct.rb @@ -415,11 +415,13 @@ def test_class def test_pattern_matching os = OpenStruct.new(class: 'my-class', method: 'post') - case os - in { class: 'my-class', method: 'post' } - assert true - else - assert false - end - end + instance_eval(<<~RUBY) + case os + in { class: 'my-class', method: 'post' } + assert true + else + assert false + end + RUBY + end if RUBY_VERSION >= '2.7' end