From: Robert Klemme Date: 2007-06-27T19:40:01+09:00 Subject: Re: Fun about inspect On 26.06.2007 23:42, Victor "Zverok" Shepelev wrote: > Hi all. > > By some complex reasons, I've made an interesting conclusion: for > "serializable" types it's always good to have eval(obj.inspect) == obj > > For me it was a good thought, because previously, I've always doubt what > #inspect should do, and typically have ended with #inspect as alias for > #to_s > > Here is a dumb test for some core classes: > > # dumb testing function > # tests, if eval(obj.inspect) == obj, and if any > # parsing errors are thrown by evaluating > # > def tst(obj) > begin > print "testing %-10.10s: " % obj.class.name > res = eval(obj.inspect) > if res == obj > puts 'OK' > else > print 'WRONG : ' > puts "\t%-7s => %-7s" % [obj.inspect, res.inspect] > end > rescue Exception > puts "ERROR" > end > end > > #the tests itself > > tst(5) #=> OK > tst("str") #=> OK > tst(RuntimeError.new) #=> WRONG : # => nil > > tst([1,2,3]) #=> OK > tst(:a => 1) #=> OK > tst(Time.new) #=> ERROR > > There are several interesting things to note: > * basic types (Numeric, String, Array, Hash) are all behave good here. No, they don't. See below. > * Exception descendants are evaluated to nil, which can be considered OK, as > we typically not plan to serialize and store exceptions. Even in this case, > results of #inspect are evaluated without any error! > * But Time is a bad guy! It's #inspect result is something like "Wed Jun 27 > 00:36:12 +0300 2007" and is equal to it's #to_s result and can't be > evaluated in any manner. I think, it's not the most reasonable variant. > > What do you think? I think nobody should rely on #inspect creating something that will be able to resurrect the original. Note, that it does not even work properly for Hashes: irb(main):001:0> h1 = Hash.new 666 => {} irb(main):002:0> h1[:foo] => 666 irb(main):003:0> s1 = h1.inspect => "{}" irb(main):004:0> h2 = eval s1 => {} irb(main):005:0> h2[:foo] => nil The sole purpose of #inspect is to return something that will reveal human readable information about an object's state which can be used for logging and debugging. By no means #inspect is meant for serialization, that's what Marshal, YAML and the likes are for. Kind regards robert