From: Michael Neumann Date: 2001-09-21T08:49:51+09:00 Subject: [ruby-talk:21475] Re: chain methods inside and outside the class; how to intermingle mine and Strings' methods? Tobias Reif wrote: > Frykholm, Niklas wrote: > > > > With this modification you can do this. h.upcase in String does not > > return a String, it returns an object of the same type as h (in > > this case a HoX). This is what makes it possible to chain calls in > > this way. > > > > Your class, HoX should be as polite, that is why delete_digits > > should use self.class.new rather than HoX.new, it makes it possible > > for someone to create a subclass of HoX and chain the method > > calls. > > > Here is the new version, thanks a lot. > > But I have a new question: > > --file begin-- > > class HoX < String > > def delete_digits > self.class.new self.gsub /\d/,'' > end > > def repeat > self.class.new self.dup * 2 > end > > def all > delete_digits.repeat > end > > end > > h = HoX.new 'a1b1c1' > > # works, because h.upcase returns a HoX > intermingled01 = h.repeat.upcase.delete_digits > puts intermingled01 # -> ABCABC > > # doesn't work, because h.reverse returns a String > # intermingled02 = h.repeat.reverse.delete_digits > # puts intermingled02 # -> ~ "undefined method 'delete_digits' for > "...":String" Write a Delegator class that delegates all String methods to the internal-hold String object, checks if the return value of it is a String, in which case you create a new HoX object that holds the String internally. class HoX def initialize(str) @str = str end def to_s @str end def method_missing(id, *args, &b) ret = @str.send(id, *args, &b) if ret.is_a? String type.new(ret) else ret end end def delete_digits type.new( @str.gsub(/\d/,'') ) end def repeat type.new( @str.dup * 2 ) end def all delete_digits.repeat end end -------- Regards, Michael -- Michael Neumann merlin.zwo InfoDesign GmbH http://www.merlin-zwo.de