diff --git a/lib/ostruct.rb b/lib/ostruct.rb index a08561d..99f7dc1 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] = public_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..177c9d0 100644 --- a/test/ostruct/test_ostruct.rb +++ b/test/ostruct/test_ostruct.rb @@ -412,4 +412,16 @@ 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') + 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