Undocumented behaviour of Array#join

Guys,

Have you ever seen this ?

2.1.2 :001 > [2,[3,4],1,8,[[[5]]]].join
=> “234185”
2.1.2 :002 > [2,[3,4],1,8,[[[5]]]].join("|")
=> “2|3|4|1|8|5”
2.1.2 :003 >

Regards,
Arup R.

Wow

I tried this just for check and behaves the same

[2,[3,4],1,8,[[[5]]]] * ‘|’
=> “2|3|4|1|8|5”

2014-08-05 8:15 GMT-03:00 Arup R. [email protected]:

Seems like it joins the array recursively. Source:

https://github.com/ruby/ruby/blob/trunk/array.c#L1979

On Tue, Aug 5, 2014 at 6:15 AM, Arup R.
[email protected]
wrote:

Have you ever seen this ?

2.1.2 :001 > [2,[3,4],1,8,[[[5]]]].join
=> “234185”
2.1.2 :002 > [2,[3,4],1,8,[[[5]]]].join(“|”)
=> “2|3|4|1|8|5”
2.1.2 :003 >

As #join returns a String, I’m sort of wondering what else you were
expecting it to do?

This has been standard behaviour since at least 1.8.7

True, it’s not well documented.​

I think he expected a failure.

2014-08-05 19:15 GMT-03:00 tamouse pontiki [email protected]:

Another possible expectation could be that it works like this:

class Array
def join sep=$,
reduce do |s,e|
s.to_s + sep.to_s + e.to_s
end.to_s
end
end

(Apologies for suboptimal to_s, but you get the idea). Which, depending
on
Array#to_s, could do the following:

[1,[2,3]].join ‘|’
#=> “1|[2, 3]” in 1.9+, or

“1|23” in 1.8

Note that the following already happens:

[1,{2=>3}].join ‘|’
#=> “1|{2=>3}” in 1.9+, or
#=> “1|23” in 1.8

And it doesn’t matter if you define Hash#join, the recursion only
happens
if the object is_a? Array.

So, again, the documentation is lacking.

On Wed, Aug 6, 2014 at 12:52 AM, Matthew K. [email protected]
wrote:

Another possible expectation could be that it works like this:

class Array
def join sep=$,
reduce do |s,e|
s.to_s + sep.to_s + e.to_s
end.to_s
end
end

Or, probably a tad more efficient

class Array
def join2(sep = $,)
sep = sep.to_s

reduce nil do |s,e|
  if s
    s << sep << e.to_s
  else
    e.to_s
  end
end

end
end

Another way to achieve that would be

irb(main):003:0> [2,[3,4],1,8,[[[5]]]].map(&:to_s).join(“|”)
=> “2|[3, 4]|1|8|[[[5]]]”

#=> “1|{2=>3}” in 1.9+, or
#=> “1|23” in 1.8

And it doesn’t matter if you define Hash#join, the recursion only happens if
the object is_a? Array.

So, again, the documentation is lacking.

I agree.

Kind regards

robert