From: Sam Roberts Date: 2005-03-14T06:49:34+09:00 Subject: Re: how do I convince Hash that two keys are the same? Quoting ruby-ml@magical-cat.org, on Mon, Mar 14, 2005 at 06:08:35AM +0900: > >I think Str#downcase should return the same thing as String#downcase => > >a String, and not a Str, so I don't see why there is a recursive call, > >here. > > When you derive, you establish an is_a relationship. Str is_a String. > All methods are also derived so you're actually calling Str#downcase, > although the code being executed was defined in String. I don't think thats the answer, its not how things normally work. String#to_s doesn't work that way, for example, despite the docs saying it does, it returns an object of class String, even if the receiver isn't of class String. It looks like String.upcase is creating a new instance of its derived class, but somehow bypassing the derived classes initialize, see example below. I don't understand how it does this. I thought it might be calling self.class.new, but it doesn't. For example, how would I do this so it has the same behaviour as #downcase, returning an object of the derived class: class String def brackets self.class.new("(" + self + ")") end end The above doesn't work, so how would I do it? Hm, maybe self.copy.tr(..) is what its doing... I guess I should read the String src code. Cheers, Sam Run the following through irb. class String def brackets self.class.new("(" + self + ")") end end class Str < String def initialize(s) puts '!Str' super(s) end end class Now < String def initialize puts '!Now' super(Time.now.to_s) end end class Now2 < String def initialize(a,b) puts "!Now2 #{a} #{b}" super(Time.now.to_s) end end Str.new('aa').upcase Str.new('aa').upcase.class Now.new.upcase Now.new.upcase.class Now2.new(1,2).upcase Now2.new(1,2).upcase.class Str.new('aa').brackets Now.new.brackets Now2.new(1,2).brackets Str.new('aa').to_s.class Now.new.to_s.class Now2.new(1,2).to_s.class