Robert Klemme
6/27/2007 10:35:00 AM
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 : #<RuntimeError: RuntimeError> => 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