diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2005-09-05 08:10:23 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2005-09-05 08:10:23 +0000 |
commit | fe5473f27c5cf081a1bfb2c39e8aea40799ec2fb (patch) | |
tree | 155452cc9567e0da38a04383755614a72c44c2f5 /lib/ostruct.rb | |
parent | 260231d3f6bba0e0fde81e78a5e145dafe5e8824 (diff) |
* lib/ostruct.rb: a patch from Florian Gross <florgro@gmail.com>
merged to allow recursive inspect (and to_s) for OpenStruct.
[ruby-core:05532]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@9079 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/ostruct.rb')
-rw-r--r-- | lib/ostruct.rb | 41 |
1 files changed, 30 insertions, 11 deletions
diff --git a/lib/ostruct.rb b/lib/ostruct.rb index b30ae640c5..6af5bbdac0 100644 --- a/lib/ostruct.rb +++ b/lib/ostruct.rb @@ -47,7 +47,7 @@ class OpenStruct @table = {} if hash for k,v in hash - @table[k.to_sym] = v + @table[k.to_sym] = v new_ostruct_member(k) end end @@ -68,11 +68,11 @@ class OpenStruct end def new_ostruct_member(name) + name = name.to_sym unless self.respond_to?(name) - self.instance_eval %{ - def #{name}; @table[:#{name}]; end - def #{name}=(x); @table[:#{name}] = x; end - } + meta = class << self; self; end + meta.send(:define_method, name) { @table[name] } + meta.send(:define_method, :"#{name}=") { |x| @table[name] = x } end end @@ -81,14 +81,14 @@ class OpenStruct len = args.length if mname =~ /=$/ if len != 1 - raise ArgumentError, "wrong number of arguments (#{len} for 1)", caller(1) + raise ArgumentError, "wrong number of arguments (#{len} for 1)", caller(1) end if self.frozen? - raise TypeError, "can't modify frozen #{self.class}", caller(1) + raise TypeError, "can't modify frozen #{self.class}", caller(1) end mname.chop! - @table[mname.intern] = args[0] self.new_ostruct_member(mname) + @table[mname.intern] = args[0] elsif len == 0 @table[mid] else @@ -103,16 +103,35 @@ class OpenStruct @table.delete name.to_sym end + InspectKey = :__inspect_key__ # :nodoc: + # # Returns a string containing a detailed summary of the keys and values. # def inspect - str = "<#{self.class}" - for k,v in @table - str << " #{k}=#{v.inspect}" + str = "#<#{self.class}" + + Thread.current[InspectKey] ||= [] + if Thread.current[InspectKey].include?(self) then + str << " ..." + else + first = true + for k,v in @table + str << "," unless first + first = false + + Thread.current[InspectKey] << v + begin + str << " #{k}=#{v.inspect}" + ensure + Thread.current[InspectKey].pop + end + end end + str << ">" end + alias :to_s :inspect attr_reader :table # :nodoc: protected :table |