On Sunday, June 27, 2004, at 05:20  PM, Sean O'Dell wrote:

> On Sunday 27 June 2004 13:44, Patrick May wrote:
>>
>> Is the problem that you want to add methods?  Then use Modules.
>
> This is a good question.  In the past, I've wished I could change 
> objects into
> a different state, sort of like taint or freeze, but with a little more
> customization.  For example, taking a File object and replacing all of 
> its
> write methods to custom ones that log everything written.  It can be 
> done by
> adding methods (and removing methods ones you don't want to be 
> available
> anymore), but I thought a really super simple way to handle the 
> situation is
> to simply replace the entire class of the object, so you control 100% 
> what
> methods are available.  That way, if the File object got passed to 
> some other
> method out of your control that called a method you forgot to replace 
> or
> remove, the method wouldn't even be there.

Delegation sounds like the solution here, either hand coded or with 
SimpleDelegator.

> Of course, like I said, the Ruby internals make difficult to make a 
> stable
> feature, so the point is probably moot.  But what I found interesting 
> was how
> easy it was to change an object's class in C, and to provide a fair 
> amount of
> protective code by simply adding a Check_Type call to the R* macros.

Protecting Ruby from a segfault is not going to insure that all 
changling objects work properly.

How can any class, not just the Ruby internals, make an intelligent 
decision about how to initialize an instance from a random operand?

The problem with #become / #class=  is that it implies one can easily 
change the class of any object into any other object.  Changing the 
class is easy, but for the new object to work the new class has to map 
the state and semantics of the old class into the state and semantics 
of the new class.  The #update_instance_for_changed_class tries to 
solve this problem, but this is poor encapsulation.  For #become to be 
safe and easy, every class has to know details of the internal state of 
every other class.

Again, why should every class be saddled with the responsibility of 
knowing the internal semantics of literally *every* other class in the 
system?  Those #update_instance_for_changed_class methods keep getting 
larger and larger....

#become / #class= is an interesting thought experiment, but it becomes 
absurd when I imagine what it would take to make it work properly.  
These methods shift a responsibility that is easiest to handle outside 
a class into somewhere it doesn't belong.   That is ugly, difficult, 
and not Ruby-like IMHO.

Cheers,

Patrick