From: Gavin Sinclair Date: 2004-04-05T09:22:22+09:00 Subject: Difference between to_s and to_str There has been some discussion on this topic in the thread "deciding between ruby and python". It was centered around how far #join should go in getting what it wants (a String) from an object. I detected some misunderstanding at the intention of #to_s and #to_str, so I hope the following is helpful (and more importantly, correct). #to_s is for providing a String *representation* when the caller explicitly wants a string, e.g. for rendering purposes. For example, Integer#to_s gives you a nice string representation of an integer, which is pretty straightforward. #to_str is for providing a String *version* when the caller *implicity* wants a string, e.g. parameter passing. The motivation here is typically for the class to fit in with the standard Ruby classes. For example, the Pathname class (in stdlib) represents a path to a file and has all sorts of funky path manipulation capabilities. But since a path **is essentially a String** it makes sense to provide Pathname#to_str so the following lines work: File.open(pathname) message = "Can't find directory: " + pathname Naturally, Pathname will also provide #to_s, and it will probably be the same as #to_str. However, Integer does not provide #to_str, because despite there being a String *representation* of an integer, there is no String *version* of an integer. If Integer#to_str were provided, then the following would "work": "1" + 7 # "17" (yuck!) And if you *really* want Perl, implement String#to_int so you can do 1 + "7" # 8 (YUCK!!!) A relevant point should be made here about #to_s. It provides *a* string representation of an object. There is no such thing as *the* string representation of an object. Even the humble integer, whose string rep is pretty damn obvious, is up for discussion. Do we want -14.to_s # "-14" or -14.to_s # "(14)" or even -14.to_s # "(14)" ? Because of these different demands in different contexts, class authors should be mindful of providing a #to_s implementation that is not "obvious" and clearly desirable in a majority of cases. I remember redefining #to_s at an object level, not a class level, because its output was too long. It was conceptually correct in what it was trying to provide, but for my purposes (unit testing) it was simply too long. REXML could do with some work on its #to_s methods. Take a large XML document, select a (small) node within it and call #to_s, and go make yourself a coffee while it prints reams of stuff to the screen :) Cheers, Gavin