defining to_s works oddly?

M

Martin Elzen

Hi all. Am I the only one that finds it odd that if I define a to_s
function for a class, that if I do:
puts obj

I won't get errors, but if I try something like:
s = String.new
s += obj

I get a 'can not convert a <class type>' into String type error'...

It's no prob to write obj.to_s, it's just I expected the first version to
call to_s automatically...

Martin

PS for clarity, my complete error producing example is as follows:

class Animal

def initialize(name)
fail "name is nil" if name.nil?

@name = name
end


def to_s
"#{@name}"
end

end



c = Animal.new('Snoes')

puts c

puts "substituted in a string literal: #{c}"


s = String.new
s += c

#puts s
 
B

Brad Wilson

------=_Part_2943_23479942.1122391429631
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

To make a rough guess? So that you can say 'this is my human readable=20
version' (to_s) vs. 'this is how you convert me to a string' (to_str).

=20

=20
I'm curious about that... why the two methods, to_s/to_str? I know
it's been discussed before, and I *think* I understood it then, but
I've since forgotten and there are probably others who haven't heard
the explanation before.
=20
Jacob Fugal
=20
=20


--=20
Brad Wilson
http://www.dotnetdevs.com/
http://www.agileprogrammer.com/dotnetguy/

Peter: "Oh my god, Brian, there's a message in my Alphabits. It says,=20
'Oooooo.' "
Brian: "Peter, those are Cheerios."
- Family Guy

------=_Part_2943_23479942.1122391429631--
 
D

Daniel Brockman

Hi Martin,
Am I the only one that finds it odd that if I define a
to_s function for a class, that if I do

puts obj

I won't get errors, but if I try something like

s =3D String.new
s +=3D obj

I get a [TypeError]

You're probably not the only one. The reason why =E2=80=98puts=E2=80=99
converts its argument using =E2=80=98to_s=E2=80=99 but String#+ doesn't i=
s
far from obvious.
It's no prob to write obj.to_s, it's just I expected the
first version to call to_s automatically...

As James Edward Gray II quoted Why saying, =E2=80=9Cto_str is an
implicit cast, whereas to_s is an explicit cast,=E2=80=9D and you
could probably redefine String#+ to perform the explicit
cast instead of the implicit with no problems resulting.

But I wouldn't do that. There is a significant difference
between =E2=80=98"#{foo}"=E2=80=99 (or =E2=80=98puts foo=E2=80=99) and =E2=
=80=98"bar" + foo=E2=80=99:
The former *must* result in a string, whereas the latter
could reasonably result in something other than a string.

Consider these two expressions:

"1" + 2 and 1 + "2"

Current Ruby behavior is to reject both with type errors.
See, Fixnum#+ implicitly casts its argument into a number,
and String#+ implicitly casts its argument into a string,
but neither argument can be implicitly casted that way.

[Again, the term =E2=80=9Cimplicit cast=E2=80=9D is not an exact descript=
ion
of what happens, but rather a shorter way of saying =E2=80=9Cconvert
if possible and fail otherwise.=E2=80=9D]

You could make either method use an explicit cast instead of
an implicit, but if you make both explicit you would be in
the following weird situation:

"1" + 2 #=3D> "12"

1 + "2" #=3D> 3

Assuming you agree that this asymmetry is unacceptable,
the question is, which cast should take precedence?

Perl avoids this ambiguity by letting "1" =3D=3D 1, so that

"1" + 2 =3D=3D 1 + "2" =3D=3D "3" =3D=3D 3.

Ruby avoids it by requiring an explicit cast:

"1" + 2.to_s #=3D> "12"

1.to_s + "2" #=3D> "12"

1 + "2".to_i #=3D> 3

"1".to_i + 2 #=3D> 3


I know this message doesn't provide any solutions, but I
hope it can help you accept Ruby's behavior as reasonable
(something I consider very important for trust reasons).

--=20
Daniel Brockman <[email protected]>

So really, we all have to ask ourselves:
Am I waiting for RMS to do this? --TTN.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,962
Messages
2,570,134
Members
46,690
Latest member
MacGyver

Latest Threads

Top