On Mar 1, 10:41 am, Brian Candler <B.Cand... / pobox.com> wrote:
> On Thu, Mar 01, 2007 at 05:38:50PM +0900, Nanostuff wrote:
> > That's pretty much my question :) Thanks.
>
> So you can write
>   a += b.to_i
> or
>   puts c   # which calls an implied #to_s
>
> without getting an error if the argument already *is* an integer or a
> string.
>
> Now, as to why there are both #to_i and #to_int, and #to_s and #to_str, I
> have no idea :-)

That's because those pairs of methods have different roles. The
difference is subtle, but important:
- #to_i and #to_s are conversion methods. They are used when one wants
a *representation* of an object as an integer or a string. Nothing
more, nothing less.
- #to_int and #to_str are duck-typing methods, basically. In other
words, they are methods that indicate that an object is Integer-like
or String-like. The difference is a semantic one rather than a
syntactic one. By supplying #to_str for instance, an object is
agreeing to be used when a string would normally be, and react like a
string in string contexts.

If you check the Core API on http://www.ruby-doc.org, you'll see for
instance that about a hundred classes implement #to_s, but only three
implement #to_str. That's because of their semantic difference: Float
can easily implement #to_s, since it's absolutely normal for numbers
to have a string representation. However, it doesn't implement
#to_str, because if it did it would basically be like saying that
Floats are like strings, which they are of course not. On the other
hand, Float implements both #to_i and #to_int because Floats can, as
fellow numbers, be used where Integers would be. They are Integer-like
enough.

Basically, look at #to_i and #to_s as giving representations, while
#to_int and #to_str are the sign that an object has a contract to
behave like an Integer or a String in corresponding contexts.