On Monday 28 June 2004 10:06, Mikael Brockman wrote: > "Sean O'Dell" <sean / celsoft.com> writes: > > On Monday 28 June 2004 09:27, Austin Ziegler wrote: > > > On Tue, 29 Jun 2004 00:58:22 +0900, Sean O'Dell <sean / celsoft.com> wrote: > > > > #class= can only be called on existing objects, so it can't prevent > > > > initialization from happening (it already happened before you can > > > > even make the call). The takeover class inherits an > > > > already-initialized object. I'm not sure how else to say that. The > > > > object is already initialized, #class= cannot prevent that. Both > > > > classes, the old and the new, work with an already-initialized > > > > object. > > > > > > So ... with your modifications, I can safely do: > > > > > > foo = Object.new > > > foo.class = Tempfile > > > foo.write "bar" > > > > Safely, yes. Usefully, no. Tempfile can't do much with just an Object > > instance, and since its methods expect its own data and nothing else, it > > really would just complain that it can't do anything useful. > > > > However: > > > > socket.class = SocketLogger > > > > ...would be a case where something useful DID happen. Assume you get > > socket in a callback method of, say, an HTTP server framework. You can't > > figure out why your client code isn't getting the data you think your > > callback method is sending through the socket object. So, as a debugging > > trick, you swap out the socket object with a SocketLogger, which still > > sends data through the socket, but also logs everything sent by your > > method as well as the framework, so you can see everything going out by > > just analyzing a logging file. From that point on out, every method call > > made on the socket object would be handled by the SocketLogger class; no > > calls could slip through to the old Socket class and go unnoticed > > accidently. > > > > Both #class= and #become, I think, would serve this purpose. I like > > #become for its safety, but I boggle at how you would located every > > single reference to an object both in Ruby and in C extensions. Also, > > there's the chance that an object could #become to another class and > > still be assigned methods which expect certain data to be initialized > > which is not, and you could still end up with the same dangers as > > #class=. > > > > Sean O'Dell > > evil.rb implements #become without traversing the entire set of live > references; it simply alters the objects in place, I think. > > With just #become (no class=), you can't create objects whose > #initialize is not called. It's just like swapping variables, except > all variables that point to the pointee are affected. You can't do that with #class= either. You can only call #class= on objects that exist, hence they've been initialized. The new class might not know what to do with the object, but the object certainly has already been initialized. Sean O'Dell