diff options
author | eregon <eregon@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-10-14 16:57:21 +0000 |
---|---|---|
committer | eregon <eregon@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-10-14 16:57:21 +0000 |
commit | 3bf9b2f0473550caa73468908ac3e18e0f431b85 (patch) | |
tree | c328528a8524720a1e9d7b70e944730906a5623a | |
parent | 5c7f36a1b81216d1a31652c54b628bc364f08245 (diff) |
* lib/ostruct.rb: Finish defining OpenStruct attributes lazily.
Patch by @sferik in [GH-1037]: https://github.com/ruby/ruby/pull/1037
This commit is an addendum to https://github.com/ruby/ruby/pull/1033.
It:
1. lazily defines attribute accessors for copied and marshaled objects,
2. returns nil when an attribute reader is not defined, and
3. defines respond_to_missing? to maintain the same respond_to? behavior
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52125 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | lib/ostruct.rb | 12 |
2 files changed, 19 insertions, 3 deletions
@@ -1,3 +1,13 @@ +Thu Oct 15 01:49:25 2015 Benoit Daloze <[email protected]> + + * lib/ostruct.rb: Finish defining OpenStruct attributes lazily. + Patch by @sferik in [GH-1037]: https://github.com/ruby/ruby/pull/1037 + This commit is an addendum to https://github.com/ruby/ruby/pull/1033. + It: + 1. lazily defines attribute accessors for copied and marshaled objects, + 2. returns nil when an attribute reader is not defined, and + 3. defines respond_to_missing? to maintain the same respond_to? behavior + Wed Oct 14 16:56:50 2015 Nobuyoshi Nakada <[email protected]> * configure.in: check for libunwind.h, which is not available in diff --git a/lib/ostruct.rb b/lib/ostruct.rb index a48ae9af05..63146075be 100644 --- a/lib/ostruct.rb +++ b/lib/ostruct.rb @@ -98,7 +98,6 @@ class OpenStruct def initialize_copy(orig) super @table = @table.dup - @table.each_key{|key| new_ostruct_member(key)} end # @@ -140,7 +139,6 @@ class OpenStruct # def marshal_load(x) @table = x - @table.each_key{|key| new_ostruct_member(key)} end # @@ -172,6 +170,11 @@ class OpenStruct end protected :new_ostruct_member + def respond_to_missing?(mid, include_private = false) + mname = mid.to_s.chomp("=").to_sym + @table.key?(mname) || super + end + def method_missing(mid, *args) # :nodoc: len = args.length if mname = mid[/.*(?==\z)/m] @@ -180,7 +183,10 @@ class OpenStruct end modifiable[new_ostruct_member(mname)] = args[0] elsif len == 0 - @table[mid] + if @table.key?(mid) + new_ostruct_member(mid) + @table[mid] + end else err = NoMethodError.new "undefined method `#{mid}' for #{self}", mid, args err.set_backtrace caller(1) |