On Sunday 18 February 2001 20:43, David Alan Black wrote: > On Mon, 19 Feb 2001, craig duncan wrote: > > Ben Tilly wrote: > > > craig duncan <duncan / nycap.rr.com> wrote: > > > >Yukihiro Matsumoto wrote: > > > > > 'to_s' is a mean to convert something into a string (if you really > > > > > want to), OTOH 'to_str' is a mean for something that wants to > > > > > pretend to be a string. to_a and to_ary are in similar > > > > > relationship. > > > > > > > >The problem with this explanation is that i have no idea what it means > > > > for something to "pretend to be a string" as opposed to being one. > > > > > > Think of it this way. foo.to_s tells foo to describe itself > > > as a string. foo.to_str checks with foo that it is OK to > > > think of foo as being its description, and gets that > > > description. > > > > > > So to_str is the same as to_s except with an extra assertion > > > about the correct usage of that object. > > > > Wow! That was a little too subtle for me to guess. I think because of > > the minimalism that i (initially) perceive to be lacking in this design. > > to_str can always fill in for to_s, yes? > > No, because to_s is inherited from Object by every object, whereas > to_str is only defined for a couple of built-in types (String, > Exception). > > > So what do you need to_s for? I guess you could say that you use > > to_s when you _don't_ want the object to be used as a string > > . . . even though you want it to _appear_ that way. ? Oh, well, i > > guess i can accept that there _might_ be some usage for that > > distinction (can't think what, though). Thanks, Ben. > > Here's my current understanding of it, for what it's worth: > > Every object will respond to to_s, and to_s will always give you > *something*. But sometimes you might want a given class to have a > non-canonical way of showing itself as a string. In such a case, you > can define a to_str method, such that your objects have their own idea > of how to represent themselves as strings. > > A little test/demo: > > class Pretender > > attr_reader :to_str > > def initialize(s) > @to_str = "I am a Pretender object initialized with #{s}." > end > > end > > p = Pretender.new(Math::PI) > > puts "Canonical/inherited conversion to string:" > puts p.to_s > puts > puts "Pretender object's own choice as to how to appear as a string:" > puts p.to_str > > > Once an object has its to_str method, it will be able to respond with > something when it is asked to do so by (for example) String#<<. > > Or, consider that varying methods either assume an object is a string and rasie an excpetion if it is not (e.g. puts) or make no such assumption but does the conversion internally (e.g print) so that for: list = ['test', 2, false, 2.3] the following: list.each { |i| print i, "\n" } list.each { |i| puts i.to_s } produce the same result, but: list.each { |i| puts i } raises an exception. Now, class Array (v 1.62) does not have a built-in to_str method, but it can, as in: class Array def to_str(x='') s = '' self.each { |i| s += i.to_s + x } s =~ /^(.*)#{s}$/ $1 end end which produces the following: list.to_str #-> 'test2false2.3' list.to_str "\s" #->'test 2 false 2.3' list.to_str "," #->'test,2,false,2.3' list.to_str '::' #->'test::2::false::2.3' thus showing one of the main benefts of Ruby, which is if core functionality is 'lacking' for a specific user need, the user simply rolls his/her own! :-) BTW list.to_str "\n" per the above -> nil. Does this violate POLS? No. As written, the method thus called should return nil. A non-string argument raises an exception. It should...it is a very poorly written method! :-) Regards, Kent Starr elderburn / mindspring.com raises an excpetion.