From: gwtmp01@... Date: 2006-12-01T13:40:35+09:00 Subject: puts, print, Array#to_s relative to ruby 1.8 and 1.9 On Nov 30, 2006, at 2:39 PM, dblack@wobblini.net wrote: > And, I now realize, if someone posted what I posted and I were > responding to it, I would point out that: > > array.each {|e| puts e } > > is the same as: > > puts array > > Something I've described in the past as a nuby rite of passage, I > believe... :-) I find it a bit strange that puts treats array objects differently than all other objects. Strings are simply written to stdout, objects other than arrays are converted to strings by calling to_s and then written, but arrays are handled via the recursive algorithm shown above. The effect is to 'flatten' recursive array structures and then write the to_s version of each object on a separate line. My expectation was that Array#to_s would be called for array arguments but it turns out that Array#to_s doesn't generate the same results as the recursive algorithm that Dave shows above. Even more puzzling is that IO#print doesn't treat array objects specially, and simply calls Array#to_s. Prior to 1.8, Array#to_s simply concatenated the results of calling #to_s on each element of the array. In 1.9 Array#to_s generates an inspect-like string for the array: ruby 1.8.5: [1,2].to_s => 12 ruby 1.9: [1,2].to_s => [1, 2] ruby 1.8.5: print [1,2] => 12 ruby 1.9: print [1,2] => [1, 2] ruby 1.8.5: puts [1,2] => 1\n2\n ruby 1.9: puts [1,2] => 1\n\2\n I guess that the puts behavior is in some sense a shortcut for a common need (instead of writing puts *a.flatten), but it seems anomalous to me. If you use nested arrays to model a tree structure then Array#to_s is a very nice way to do a pre-order traversal of the structure generating a textual representation of the tree. This works just fine in 1.8, but in 1.9 you get burned. I suspect that there might be quite a bit of code that expects the 1.8 behavior for Array#to_s than the 1.9 behavior. Maybe I'm missing something but I think to get the 1.8 Array#to_s behavior in 1.9 you would have to write something like: a.flatten.inject("") { |s,i| s << i.to_s } Gary Wright