aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--lib/ostruct.rb18
-rw-r--r--test/ostruct/test_ostruct.rb11
3 files changed, 34 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 48e4ed11f6..e6b5b94a42 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Tue Nov 17 14:36:00 2015 Kenichi Kamiya <kachick1@gmail.com>
+
+ * lib/ostruct.rb (dig): Implement OpenStruct#dig
+ [Feature #11688]
+
Tue Nov 17 14:04:14 2015 NAKAMURA Usaku <usa@ruby-lang.org>
* ext/socket/lib/socket.rb (Socket#recvmsg{,_nonblock}): default values
diff --git a/lib/ostruct.rb b/lib/ostruct.rb
index 63146075be..0e13f40692 100644
--- a/lib/ostruct.rb
+++ b/lib/ostruct.rb
@@ -215,6 +215,24 @@ class OpenStruct
end
#
+ # Retrieves the value object corresponding to the each +name+
+ # objects repeatedly.
+ #
+ # address = OpenStruct.new('city' => "Anytown NC", 'zip' => 12345)
+ # person = OpenStruct.new('name' => 'John Smith', 'address' => address)
+ # person.dig(:address, 'zip') # => 12345
+ # person.dig(:business_address, 'zip') # => nil
+ #
+ def dig(name, *names)
+ begin
+ name = name.to_sym
+ rescue NoMethodError
+ return
+ end
+ @table.dig(name, *names)
+ end
+
+ #
# Remove the named field from the object. Returns the value that the field
# contained if it was defined.
#
diff --git a/test/ostruct/test_ostruct.rb b/test/ostruct/test_ostruct.rb
index 2e8fc7bf58..d8d4cd30f0 100644
--- a/test/ostruct/test_ostruct.rb
+++ b/test/ostruct/test_ostruct.rb
@@ -108,6 +108,17 @@ class TC_OpenStruct < Test::Unit::TestCase
assert_equal :bar, os['foo']
end
+ def test_dig
+ os1 = OpenStruct.new
+ os2 = OpenStruct.new
+ os1.child = os2
+ os2.foo = :bar
+ os2.child = [42]
+ assert_equal :bar, os1.dig("child", :foo)
+ assert_nil os1.dig("parent", :foo)
+ assert_nil os1.dig("child", 0)
+ end
+
def test_to_h
h = {name: "John Smith", age: 70, pension: 300}
os = OpenStruct.new(h)