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?
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.