From: Eric Mahurin Date: 2005-10-27T21:52:56+09:00 Subject: Re: overriding #inspect --- Sean O'Halpin wrote: > On 10/26/05, Eric Mahurin wrote: > > > --- Sean O'Halpin wrote: > > > > > > > On 10/26/05, Eric Mahurin > wrote: > > > > > Anybody know what the best way to override inspect > where > > > > you > > > > > may have a recursive data structure? > > > > > > > > Check out Tanaka Akira's 'pp' lib (if only to convince > > > > yourself that > > > > there's no silver bullet!) > > > > Actually, as soon as I allowed myself to make an instance > > variable, it didn't seem so bad. Here's what I came up > with: > > > > def inspect > > to_s[0..-2].concat(" #{ > > if defined?(@inspecting) > > "..." > > else > > begin > > @inspecting = true > > ... generate inspect contents here ... > > ensure > > remove_instance_variable(:@inspecting) > > end > > end > > }>") > > end > > But as soon as you start using flags to guard against cycles > you have > to at least acknowledge that it won't be thread safe, unless > you take > an approach like 'pp' (which stashes object_id in > Thread.current[InspectKey]). Yep. Here's one that uses a Hash to effectively make thread local instance variables: def inspect # :nodoc: to_s[0..-2].concat(" #{ if (@inspecting||=Hash.new)[Thread.current] "..." else begin @inspecting[Thread.current] = true ... generate inspect contents here ... ensure @inspecting.delete(Thread.current) end end }>") end This seems better that storing this info in thread attributes (global variables to a thread). Better encapsulation. I'm not sure how much of these operations on @inspecting are atomic, so we may need to use Thread.critical to fix this. Can we make any assumptions about what is atomic? __________________________________ Yahoo! Mail - PC Magazine Editors' Choice 2005 http://mail.yahoo.com