From: Thomas E Enebo Date: 2010-03-23T05:19:15+09:00 Subject: [ruby-core:28874] Re: WeakRef extending Delegator is a bug waiting to happen? On Mon, Mar 22, 2010 at 1:59 PM, Charles Oliver Nutter wrote: > Hopefully this doesn't contradict my other email too much :) > > In talking with Tom Enebo about Ruby's WeakRef implementation, we > concluded that it's generally not a good idea to use WeakRef like a > Delegator. In fact, it seems like WeakRef should not extend Delegator > at all. > > Here's our justification: > > * If you're using a WeakRef, you'd doing so to prevent hard references > and to potentially allow objects to be collected > * A weakly-referenced object might be collected at any time > * When working with a weakref, you should always first acquire a hard > reference to the object, so it doesn't disappear in the middle of your > code > * Allowing WeakRef to be used like Delegator means that at any time > during your code, the object could disappear and an *arbitrary method > call* could raise RefError > > Basically, using a WeakRef like a Delegator is a bug waiting to > happen, since you're almost assured that objects will disappear when > you least expect it. Also consider that every alternative Ruby implementation has GC behavior which is different than MRI's. So behavior for libraries using this feature will be inconsistent at best. Even if you only assumed a MRI GC, then code like this: begin weakref.important_call1 # ... object of weakref gets collected here ... weakref.important_call2 rescue RefError puts "rollback...just keep going...cry in fetal position" end This code is asking for weird issues since you know eventually you will lose a reference right after 'important_call1' and then be in a weird state since 'important_call2' will not happen. The only benefit to this feature is for places where you know there will be one and only one call on the weakref per transaction (transaction may not be the right word, but I think people understand what I mean). Even this seems dubious as a feature because you still need to catch the RefError. If you already have boilerplate or special error handling code do you really need to save the code needed to grab a hard reference to the object (.__getobj__) you are trying to use? Conclusion: Feature that can easily lead to unintended consequences. Weak references are needed, but should it do anything more than point to an object and be able to retrieve said object if it is still alive? -Tom PS- We see people who must have run into this on the net...things like: weakref.some_method if weakref.weakref_alive? Using the above example it should be obvious that this code is still susceptible to the same problem. -- blog: http://blog.enebo.com twitter: tom_enebo mail: tom.enebo@gmail.com