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