"Yukihiro Matsumoto" <matz / ruby-lang.org> wrote in,
....
> |Well that looks awfully close to #become to me?  Maybe also throw in an
> |optional block and/or  per and post #become hooks?  Maybe I am just
> |dreaming ...
> 
> I don't know.  But if I recall correctly, #become makes any object to
> any class, right?  It seems too strong.

I don't know if other #become implementations allow unrestricted type
change - to allow this seems rather silly to me too - clearly turning
the Class object into nil might not be such a good idea.

Anyway since nobody is taking up the issue I'll try to give the imaginary
private Object instance method 

 #become(target_type)  - returning self, but self.type == traget_type

a reasonable simple semantics.  Following your lead we simply break up
its behavior in a series of Ruby's prototypical bouncing and argument 
swaping hook calls best exemplified in the ``include'' or  ``coerce''
mechanism (making up for the lack of typed method calls).  Leaving
the ``privacy issue'' of the hooks aside the method body of #become
might be written as

    def become(target_type)
        orginal_type = self.type
        target_type._per_become(self)
        traget_type._become(self)  
        self._post_become(orginal_type)
        return self
    end

where  #_per_become , #_become are Class instance methods, ehm
better yet Object class methods with the default  implementation

    def Object._pre_become(obj)  
        raise TypeError.new  "bad idea"  unless self <= obj.type
    end
    
    def Object._become(obj)
        # unconditionally transform obj into a  self Object
    end

and  the #_post_become() hook an Object instance method which by
default does nothing.  This scheme insulates the very dangerous
part to  #_become() - and we really insulate it from rest of Ruby
by simply not  declaring it - i.e. making it ``private to the #become
call. The latter is per se an out of language feature - however harping
on a very neat trick from [ruby-talk:32488] in the recent  ``friends'' 
discussions one can probably do this in pure ruby too.

With this scheme we could easily model the strange type-modifying 
behavior of the current String implement ion. Duping in terms of a
proto Object#_dup would be straight forward too of course.  For
example,

----
class String
    def  upcase
        # current behavior
        become(type).upcase!
    end
    # other alternative
    # def upcase
    #   become(String).upcase!
    # end
end  


class HString < String
    attr_reader :orig_length
    def initialize(str)
        super
        @orig_length = length
    end
  
    private
    def _post_become(orginal_type)
        if orignal_type <= HString
            rvar=instance_variable.delete(":@orig_length")
            remove_instance_variables(*rvar)
        else
            @orig_length = length
        end
    end
end

# where
def remove_instance_variables(*vars)
  vars.each { |var|  remove_instance_variable var }
end
----


A bit of topic but related to  Dave's _Strings  class are there any plans on
a Char and/or _Char class?.


/Christoph