This is a multi-part message in MIME format.

------extPart_000_01E8_01C1A57F.A8C4BD60
Content-Type: text/plain;
	charsetso-8859-1"
Content-Transfer-Encoding: quoted-printable

Given these conditions:

  - A subclass of String or Array is defined
  - A superclass "subrange" operation is performed on an instance of the subclass (e.g. object[1 ... -1])

In the general case, the result of the operation is an invalid instance of the subclass. More specifically, if the subclass has its own instance variables, they are uninitialized.

For example, this code:

-----------------------------------------
class S < String

  def initialize(str, otherValue)
    super(str)
    @otherValue = otherValue
  end

  def inspect
    "S(otherValue: " << @otherValue.to_s << ", " << super << ")"
  end

end

s = S.new("abcdefghij", 77)
ss = s[1 ... -1]
p s
p ss

-----------------------------------------

produces the following output:

-----------------------------------------
S(otherValue: 77, "abcdefghij")
./rbug.rb:7: warning: instance variable @otherValue not initialized
S(otherValue: , "bcdefghi")
-----------------------------------------

Is this the intended consequence? For me it violated the "principle of least surprise".

This behavior means:

o   If my subclass has instance variables, I must override the subscripted operations to add my instance variables to the result.

o   If I want to return an instance of the superclass from such an operation, I have to "downcast" it by creating a new object of the superclass type (e.g. String.new(self[1 ... -1])). (Of course, it really *is* an instance of the superclass with its class changed.)

This has probably been discussed to death in the past (I'm not always tuned in to the list), but the advantages of a superclass returning (likely invalid) subclass instances are not without their downsides!


Bob

------extPart_000_01E8_01C1A57F.A8C4BD60
Content-Type: text/html;
	charsetso-8859-1"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
<META content="MSHTML 5.50.4912.300" name=GENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=#ffffff>
<DIV><FONT face=Arial size=2>Given these conditions:</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2>&nbsp; - A subclass of String or Array is 
defined</FONT></DIV>
<DIV><FONT face=Arial size=2>&nbsp; - A superclass "subrange" operation is 
performed on an instance of the subclass (e.g. object[1 ... -1])</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2>In the general case, the result of the operation is 
an invalid instance of the subclass. More specifically, if the subclass has its 
own instance variables, they are uninitialized.</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2>For example, this code:</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial 
size=2>-----------------------------------------</FONT></DIV>
<DIV><FONT face=Arial size=2>class S &lt; String<BR></FONT></DIV>
<DIV><FONT face=Arial size=2>&nbsp; def initialize(str, 
otherValue)<BR>&nbsp;&nbsp;&nbsp; super(str)<BR>&nbsp;&nbsp;&nbsp; @otherValue = 
otherValue<BR>&nbsp; end<BR></FONT></DIV>
<DIV><FONT face=Arial size=2>&nbsp; def inspect<BR>&nbsp;&nbsp;&nbsp; 
"S(otherValue: " &lt;&lt; @otherValue.to_s &lt;&lt; ", " &lt;&lt; super &lt;&lt; 
")"<BR>&nbsp; end<BR></FONT></DIV>
<DIV><FONT face=Arial size=2>end</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2>s = S.new("abcdefghij", 77)<BR>ss = s[1 ... 
-1]<BR>p s<BR>p ss<BR>
<DIV><FONT face=Arial 
size=2>-----------------------------------------</FONT></DIV>
<DIV>&nbsp;</DIV></FONT><FONT face=Arial size=2></FONT></DIV>
<DIV><FONT face=Arial size=2>produces the following output:</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2>
<DIV><FONT face=Arial 
size=2>-----------------------------------------</FONT></DIV>S(otherValue: 77, 
"abcdefghij")<BR>./rbug.rb:7: warning: instance variable @otherValue not nitialized<BR>S(otherValue: , "bcdefghi")</FONT></DIV>
<DIV><FONT face=Arial size=2>
<DIV><FONT face=Arial 
size=2>-----------------------------------------</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV>Is this the intended consequence? For me it violated the "principle of 
least surprise".</DIV>
<DIV>&nbsp;</DIV>
<DIV>This behavior means:</DIV>
<DIV>&nbsp;</DIV>
<DIV>o&nbsp; &nbsp;If my subclass has instance variables, I must override the 
subscripted operations to add my instance variables to the result.</DIV>
<DIV>&nbsp;</DIV>
<DIV>o&nbsp; &nbsp;If I want to return an instance of the superclass from such 
an operation, I have to "downcast" it by creating a new object of the superclass 
type (e.g. String.new(self[1 ... -1])). (Of course, it really *is* an instance 
of the superclass with its class changed.)</DIV>
<DIV>&nbsp;</DIV>
<DIV>This has probably been discussed to death in the past (I'm not always tuned 
in to the list), but the advantages of a superclass returning (likely invalid) 
subclass instances are not without their downsides!</DIV>
<DIV></FONT>&nbsp;</DIV></DIV>
<DIV><FONT face=Arial size=2></FONT>&nbsp;</DIV>
<DIV><FONT face=Arial size=2>Bob</FONT></DIV></BODY></HTML>

------extPart_000_01E8_01C1A57F.A8C4BD60--