In data 3/13/2005, "Sam Roberts" <sroberts@uniserve.com> ha scritto:
>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.
static VALUE
rb_str_downcase(str)
VALUE str;
{
str = rb_str_dup(str);
rb_str_downcase_bang(str);
return str;
}
VALUE
rb_str_dup(str)
VALUE str;
{
VALUE dup = str_alloc(rb_obj_class(str));
rb_str_replace(dup, str);
return dup;
}
It may not seem intuitive but it's conceptually exactly how it's
supposed to go.
>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
E