# Justification for Array#join behaviour?

**URL:** <https://rubytalk.org/t/justification-for-array-join-behaviour/35347>\
**Category:** ruby-talk\
**Created:** [14 February 2007 07:52 UTC](https://rubytalk.org/t/justification-for-array-join-behaviour/35347 "2007-02-14T07:52:00Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Farrel\_Lifson](https://avatars.discourse-cdn.com/v4/letter/f/3da27b/32.png) [@Farrel\_Lifson](https://rubytalk.org/u/Farrel_Lifson)\
**Post date:** [14 February 2007 07:52 UTC](https://rubytalk.org/t/justification-for-array-join-behaviour/35347/1 "2007-02-14T07:52:00Z")

</div>

What is the justification for [1,2,[3,4]].join(',') being '1,2,3,4'  
instead of '1,2,34'? According to [ruby-doc.org](http://ruby-doc.org) join "Returns a string  
created by converting each element of the array to a string, separated  
by sep.". Why should an element be recursively joined if it's also an  
array?

Farrel

---

<div class="post-metadata">

**Author:** ![Aur\_Saraf](https://avatars.discourse-cdn.com/v4/letter/a/bcef8e/32.png) [@Aur\_Saraf](https://rubytalk.org/u/Aur_Saraf)\
**Post date:** [14 February 2007 08:07 UTC](https://rubytalk.org/t/justification-for-array-join-behaviour/35347/2 "2007-02-14T08:07:27Z")

</div>

I second that.

> **···**
>
> On 2/14/07, Farrel Lifson \<farrel.lifson@gmail.com\> wrote:
> 
> > What is the justification for [1,2,[3,4]].join(',') being '1,2,3,4'  
> > instead of '1,2,34'? According to ruby-doc.org join "Returns a string  
> > created by converting each element of the array to a string, separated  
> > by sep.". Why should an element be recursively joined if it's also an  
> > array?
> > 
> > Farrel

---

<div class="post-metadata">

**Author:** ![Gavin\_Kistner2](https://avatars.discourse-cdn.com/v4/letter/g/b9e5f3/32.png) [@Gavin\_Kistner2](https://rubytalk.org/u/Gavin_Kistner2)\
**Post date:** [14 February 2007 15:35 UTC](https://rubytalk.org/t/justification-for-array-join-behaviour/35347/3 "2007-02-14T15:35:05Z")

</div>

What's the justification for it NOT doing that? (Just because the docs  
say so?)

I suspect that it's more like the join method #flatten s the array  
before joining, instead of recursing. But my C isn't good enough to  
tell what rb\_ary\_join is really doing inside.

I'm not sure I can think of a real use case for either scenario. The  
only one I can make up is where you want to override Array#to\_s, where  
you'd want the last line below...

irb(main):001:0\> class Foo; def to\_s;"SSS";end; def inspect;"III";end;  
end  
=\> nil  
irb(main):002:0\> a = [1, 2, Foo.new, [ 3, Foo.new, [ 4, 5] ] ]  
=\> [1, 2, III, [3, III, [4, 5]]]  
irb(main):003:0\> a.join( ',' )  
=\> "1,2,SSS,3,SSS,4,5"  
irb(main):005:0\> class Array; def to\_s; "\<hidden\>"; end; end  
=\> nil  
irb(main):006:0\> a.to\_s  
=\> "\<hidden\>"  
irb(main):008:0\> a.join( ',' )  
=\> "1,2,SSS,3,SSS,4,5"

...to return "1,2,SSS,\<hidden\>" instead.

Hrm...yeah, I think I'd prefer that simpler and more powerful  
implementation. Of course, if you really wanted it, you could change  
it yourself:

irb(main):009:0\> class Array  
irb(main):010:1\> def join( sep='' )  
irb(main):011:2\> output = ""  
irb(main):012:2\> each\_with\_index do |v,i|  
irb(main):013:3\* output \<\< v.to\_s  
irb(main):014:3\> output \<\< sep unless i == (self.length-1)  
irb(main):015:3\> end  
irb(main):016:2\> output  
irb(main):017:2\> end  
irb(main):018:1\> end  
=\> nil  
irb(main):019:0\> a.join( ',' )  
=\> "1,2,SSS,\<hidden\>"

...but (barring someone else's good explanation) I'd rather see the  
implementation changed to match the documentation (and force you to  
use a.flatten.join(',') if that's what you want) than the reverse.

> **···**
>
> On Feb 14, 12:52 am, "Farrel Lifson" \<farrel.lif...@gmail.com\> wrote:
> 
> > What is the justification for [1,2,[3,4]].join(',') being '1,2,3,4'  
> > instead of '1,2,34'? According to ruby-doc.org join "Returns a string  
> > created by converting each element of the array to a string, separated  
> > by sep.". Why should an element be recursively joined if it's also an  
> > array?

---

<div class="post-metadata">

**Author:** ![Wolfgang\_Nadasi-Don1](https://avatars.discourse-cdn.com/v4/letter/w/958977/32.png) [@Wolfgang\_Nadasi-Don1](https://rubytalk.org/u/Wolfgang_Nadasi-Don1)\
**Post date:** [14 February 2007 18:05 UTC](https://rubytalk.org/t/justification-for-array-join-behaviour/35347/4 "2007-02-14T18:05:07Z")

</div>

Farrel Lifson schrieb:

> What is the justification for [1,2,[3,4]].join(',') being '1,2,3,4'  
> instead of '1,2,34'? According to ruby-doc.org join "Returns a string  
> created by converting each element of the array to a string, separated  
> by sep.". Why should an element be recursively joined if it's also an  
> array?
> 
> Farrel

It is easy to come to the required result by

irb(main):001:0\> [1,2,[3,4]].map{|e|e.to\_s}.join(',')  
=\> "1,2,34"

...but I think this should be the "natural" way of handling it by "join". Implicit recursion (or "flatten" in this special case) can be confusing in some situation.

Wolfgang Nádasi-Donner

---

<div class="post-metadata">

**Author:** ![Bertram\_Scharpf](https://avatars.discourse-cdn.com/v4/letter/b/43a26b/32.png) [@Bertram\_Scharpf](https://rubytalk.org/u/Bertram_Scharpf)\
**Post date:** [14 February 2007 18:49 UTC](https://rubytalk.org/t/justification-for-array-join-behaviour/35347/5 "2007-02-14T18:49:42Z")

</div>

Hi,

> What is the justification for [1,2,[3,4]].join(',') being '1,2,3,4'  
> instead of '1,2,34'? According to ruby-doc.org join "Returns a string  
> created by converting each element of the array to a string, separated  
> by sep.". Why should an element be recursively joined if it's also an  
> array?

You would have to ask for the objects type:

&nbsp;&nbsp;class Array  
&nbsp;&nbsp;&nbsp;&nbsp;def deep\_join sep  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map { |x|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case x  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when Array then x.deep\_join sep  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else x.to\_s  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}.join sep  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end

I don't look at this as a smart programming style actually.

The object-oriented approach is to redefine `to\_s'.

Bertram

> **···**
>
> Am Mittwoch, 14. Feb 2007, 16:52:00 +0900 schrieb Farrel Lifson:
> 
> --  
> Bertram Scharpf  
> Stuttgart, Deutschland/Germany  
> [http://www.bertram-scharpf.de](http://www.bertram-scharpf.de)

---

<div class="post-metadata">

**Author:** ![Gary\_Wright](https://avatars.discourse-cdn.com/v4/letter/g/58956e/32.png) [@Gary\_Wright](https://rubytalk.org/u/Gary_Wright)\
**Post date:** [14 February 2007 20:22 UTC](https://rubytalk.org/t/justification-for-array-join-behaviour/35347/6 "2007-02-14T20:22:37Z")

</div>

Be aware that Array#to\_s has changed in Ruby 1.9

$ irb-1.9  
irb(main):001:0\> a = [1,2,[3,4]]  
=\> [1, 2, [3, 4]]  
irb(main):002:0\> a.to\_s  
=\> "[1, 2, [3, 4]]"  
irb(main):003:0\> a.join  
=\> "1234"  
irb(main):004:0\>

The issue is that Array#to\_s defers to Array#inspect in 1.9 instead  
of simply concatenating the results of #to\_s on all the elements.

I didn't expect this change either and matz pointed me to Array#join

Check out this thread: ruby-talk:220698

Gary Wright

> **···**
>
> On Feb 14, 2007, at 2:52 AM, Farrel Lifson wrote:
> 
> > What is the justification for [1,2,[3,4]].join(',') being '1,2,3,4'  
> > instead of '1,2,34'? According to ruby-doc.org join "Returns a string  
> > created by converting each element of the array to a string, separated  
> > by sep.". Why should an element be recursively joined if it's also an  
> > array?

---

<div class="post-metadata">

**Author:** ![Farrel\_Lifson](https://avatars.discourse-cdn.com/v4/letter/f/3da27b/32.png) [@Farrel\_Lifson](https://rubytalk.org/u/Farrel_Lifson)\
**Post date:** [14 February 2007 19:26 UTC](https://rubytalk.org/t/justification-for-array-join-behaviour/35347/7 "2007-02-14T19:26:48Z")

</div>

I did some experimentation and it seems that the decision might not  
be that half bad. Take for instance a deeply nested array  
[1,2,[3,4[5,6]]]. Currently calling join produces "1,2,3,4,5,6".  
Whereas if we used the non-recursive join we'd get "1,2,3456" which  
actually looks a bit worse. I think it would be better if the  
documentation was amended to reflect that nested arrays will be  
flattened.

Farrel

> **···**
>
> On 14/02/07, Bertram Scharpf \<lists@bertram-scharpf.de\> wrote:
> 
> > Hi,
> > 
> > Am Mittwoch, 14. Feb 2007, 16:52:00 +0900 schrieb Farrel Lifson:  
> > \> What is the justification for [1,2,[3,4]].join(',') being '1,2,3,4'  
> > \> instead of '1,2,34'? According to ruby-doc.org join "Returns a string  
> > \> created by converting each element of the array to a string, separated  
> > \> by sep.". Why should an element be recursively joined if it's also an  
> > \> array?
> > 
> > You would have to ask for the objects type:
> > 
> > &nbsp;&nbsp;class Array  
> > &nbsp;&nbsp;&nbsp;&nbsp;def deep\_join sep  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map { |x|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case x  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when Array then x.deep\_join sep  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else x.to\_s  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}.join sep  
> > &nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;end
> > 
> > I don't look at this as a smart programming style actually.
> > 
> > The object-oriented approach is to redefine `to\_s'.
> > 
> > Bertram
> > 
> > --  
> > Bertram Scharpf  
> > Stuttgart, Deutschland/Germany  
> > [http://www.bertram-scharpf.de](http://www.bertram-scharpf.de)

---

<div class="post-metadata">

**Author:** ![Martin\_DeMello](https://avatars.discourse-cdn.com/v4/letter/m/f17d59/32.png) [@Martin\_DeMello](https://rubytalk.org/u/Martin_DeMello)\
**Post date:** [15 February 2007 07:14 UTC](https://rubytalk.org/t/justification-for-array-join-behaviour/35347/8 "2007-02-15T07:14:17Z")

</div>

Or

class Object  
&nbsp;&nbsp;def join  
&nbsp;&nbsp;&nbsp;&nbsp;to\_s  
&nbsp;&nbsp;end  
end

module Enumerable  
&nbsp;&nbsp;def join  
&nbsp;&nbsp;&nbsp;&nbsp;"[" + inject {|a, e| a.join + ", " + e.join} + "]"  
&nbsp;&nbsp;end  
end

class Array  
&nbsp;&nbsp;def join  
&nbsp;&nbsp;&nbsp;&nbsp;super  
&nbsp;&nbsp;end  
end

class String  
&nbsp;&nbsp;def join  
&nbsp;&nbsp;&nbsp;&nbsp;self  
&nbsp;&nbsp;end  
end

puts [1, 2, 3, [4, 5, [6, 7], 8]].join

martin

> **···**
>
> On 2/15/07, Bertram Scharpf \<lists@bertram-scharpf.de\> wrote:
> 
> > &nbsp;&nbsp;class Array  
> > &nbsp;&nbsp;&nbsp;&nbsp;def deep\_join sep  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map { |x|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case x  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when Array then x.deep\_join sep  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else x.to\_s  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}.join sep  
> > &nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;end
> > 
> > I don't look at this as a smart programming style actually.
> > 
> > The object-oriented approach is to redefine `to\_s'.

---

<div class="post-metadata">

**Author:** ![Bertram\_Scharpf](https://avatars.discourse-cdn.com/v4/letter/b/43a26b/32.png) [@Bertram\_Scharpf](https://rubytalk.org/u/Bertram_Scharpf)\
**Post date:** [15 February 2007 11:37 UTC](https://rubytalk.org/t/justification-for-array-join-behaviour/35347/9 "2007-02-15T11:37:48Z")

</div>

Hi,

> **···**
>
> Am Donnerstag, 15. Feb 2007, 16:14:17 +0900 schrieb Martin DeMello:
> 
> > On 2/15/07, Bertram Scharpf \<lists@bertram-scharpf.de\> wrote:  
> > \>The object-oriented approach is to redefine `to\_s'.
> > 
> > Or
> > 
> > [...]  
> > puts [1, 2, 3, [4, 5, [6, 7], 8]].join
> 
> [1, 2, 3, [4, 5, [6, 7], 8]]
> 
> Ah, yes. It's the open and close delimiters () what is  
> getting lost by the OP's proposal. I should have seen that  
> right away.
> 
> Bertram
> 
> --  
> Bertram Scharpf  
> Stuttgart, Deutschland/Germany  
> [http://www.bertram-scharpf.de](http://www.bertram-scharpf.de)
