From: "Chr. Rippel" Date: 2002-01-30T00:39:34+09:00 Subject: Re: Subrange of String subclass => invalid object "Yukihiro Matsumoto" 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