diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2005-09-05 08:29:52 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2005-09-05 08:29:52 +0000 |
commit | 48653d5ef0ed47469d64170d70c8c2a9f21f159e (patch) | |
tree | df86f2bf64022459acef5eea33442fb3d3ebcc27 /lib/ostruct.rb | |
parent | f5ac36f1a3e484464d13a115bd92fa9904215201 (diff) |
* lib/ostruct.rb: a patch from Florian Gross <[email protected]>
merged to allow recursive inspect (and to_s) for OpenStruct.
[ruby-core:05532]
* lib/observer.rb: a patch from nornagon <[email protected]>
merged to allow arbitrary names for update methods.
[ruby-core:05416]
* eval.c (rb_f_fcall): new method to avoid inefficiency of
obj.instance_eval{send(...)} tricks.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9081 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 |