# Mini-RCR: Extra Argument for Array#join

**URL:** <https://rubytalk.org/t/mini-rcr-extra-argument-for-array-join/34127>\
**Category:** ruby-talk\
**Created:** [31 December 2006 20:05 UTC](https://rubytalk.org/t/mini-rcr-extra-argument-for-array-join/34127 "2006-12-31T20:05:17Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![James\_Edward\_Gray\_II](https://avatars.discourse-cdn.com/v4/letter/j/ea5d25/32.png) [@James\_Edward\_Gray\_II](https://rubytalk.org/u/James_Edward_Gray_II)\
**Post date:** [31 December 2006 20:05 UTC](https://rubytalk.org/t/mini-rcr-extra-argument-for-array-join/34127/1 "2006-12-31T20:05:17Z")

</div>

I've been looking at the to\_sentence() method in Rails. It's basically a join(), but you can give a different final separator. I personally use this kind of functionality often enough to believe it would make a good addition to the core language.

Even better, I think we can make join() smart enough to eliminate any need for to\_sentence() by adding a second argument. Here's a sample implementation:

#!/usr/bin/env ruby -w

require "enumerator"

class Array  
&nbsp;&nbsp;&nbsp;alias\_method :old\_join, :join  
&nbsp;&nbsp;&nbsp;def join(sep = $, last\_sep = sep)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return "" if empty?  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;enum\_with\_index.inject("") do |str, (e, i)|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"#{str}#{i == size - 1 ? last\_sep : sep}#{e}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end[sep.to\_s.length…-1]  
&nbsp;&nbsp;&nbsp;end  
end

if \_\_FILE\_\_ == $PROGRAM\_NAME  
&nbsp;&nbsp;&nbsp;require "test/unit"

&nbsp;&nbsp;&nbsp;class TestJoin \< Test::Unit::TestCase  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def test\_old\_matches\_new  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal([].old\_join, [].join)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal([1].old\_join, [1].join)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal([1, 2].old\_join, [1, 2].join)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal((1..5).to\_a.old\_join, (1..5).to\_a.join)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal([].old\_join("|"), [].join("|"))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal([1].old\_join("|"), [1].join("|"))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal([1, 2].old\_join("|"), [1, 2].join("|"))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal((1..5).to\_a.old\_join("|"), (1..5).to\_a.join("|"))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def test\_new\_last\_arg\_behavior  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal("1, 2, 3, 4, and 5", (1..5).to\_a.join(", ", ", and "))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal("1, 2, 3, 4 and 5", (1..5).to\_a.join(", ", " and "))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal("1, 2, 3, 4 & 5", (1..5).to\_a.join(", ", " & "))

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal([1, 2].join(","), [1, 2].join("ignored", ","))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;end  
end

\_\_END\_\_

Does anyone else like this?

James Edward Gray II

---

<div class="post-metadata">

**Author:** ![Greg\_Brown1](https://avatars.discourse-cdn.com/v4/letter/g/258eb7/32.png) [@Greg\_Brown1](https://rubytalk.org/u/Greg_Brown1)\
**Post date:** [31 December 2006 20:15 UTC](https://rubytalk.org/t/mini-rcr-extra-argument-for-array-join/34127/2 "2006-12-31T20:15:57Z")

</div>

It's neat. I think it's better than to\_sentence.

But maybe not something necessary for core.

I tend to think of join() to be a delimiter-generator, and not an  
english language generator.

But that's just my two cents. Wouldn't be opposed to an adjustment,  
but personally have never needed it for my day to day Ruby usage.

> **···**
>
> On 12/31/06, James Edward Gray II \<james@grayproductions.net\> wrote:
> 
> > Does anyone else like this?

---

<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:** [31 December 2006 20:25 UTC](https://rubytalk.org/t/mini-rcr-extra-argument-for-array-join/34127/3 "2006-12-31T20:25:09Z")

</div>

James Edward Gray II wrote:

> I've been looking at the to\_sentence() method in Rails. It's  
> basically a join(), but you can give a different final separator. I  
> personally use this kind of functionality often enough to believe it  
> would make a good addition to the core language.

What makes the final separator so special that it deserves inclusion,  
while making no allowance for a pre-separator? Just the English  
language?

(At the same time as I ask this, I'm wondering if asking for  
completeness for the sake of completeness, without a corresponding use  
case, is the sort of foolish consistency that is the hobgoblin of  
little minds.)

---

<div class="post-metadata">

**Author:** ![Ryan\_Davis1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/ryan_davis1/32/1848_2.png) [@Ryan\_Davis1](https://rubytalk.org/u/Ryan_Davis1)\
**Post date:** [31 December 2006 22:16 UTC](https://rubytalk.org/t/mini-rcr-extra-argument-for-array-join/34127/4 "2006-12-31T22:16:57Z")

</div>

problems:

1) calculating a static value inside a loop. (only costs about a hundredth of a second for 10k)  
2) iterating when 1/2 of your values are completely static.  
3) being clever by using enumerator.

class Array  
&nbsp;&nbsp;&nbsp;alias\_method :old\_join, :join  
&nbsp;&nbsp;&nbsp;def join(sep = $, last\_sep = sep)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return "" if empty?

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;seperators = Array.new(size-1, sep)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;seperators[-1] = last\_sep unless seperators.empty?  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.zip(seperators).old\_join  
&nbsp;&nbsp;&nbsp;end  
end

# of iterations = 1000000  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user system total real  
null\_time 0.140000 0.000000 0.140000 ( 0.140482)  
jeg 29.690000 0.080000 29.770000 ( 30.144816)  
ryan 19.780000 0.050000 19.830000 ( 19.998077)

> **···**
>
> On Dec 31, 2006, at 12:05 PM, James Edward Gray II wrote:
> 
> > I've been looking at the to\_sentence() method in Rails. It's basically a join(), but you can give a different final separator. I personally use this kind of functionality often enough to believe it would make a good addition to the core language.
> > 
> > Even better, I think we can make join() smart enough to eliminate any need for to\_sentence() by adding a second argument. Here's a sample implementation:
> > 
> > #!/usr/bin/env ruby -w
> > 
> > require "enumerator"
> > 
> > class Array  
> > &nbsp;&nbsp;alias\_method :old\_join, :join  
> > &nbsp;&nbsp;def join(sep = $, last\_sep = sep)  
> > &nbsp;&nbsp;&nbsp;&nbsp;return "" if empty?  
> > &nbsp;&nbsp;&nbsp;&nbsp;enum\_with\_index.inject("") do |str, (e, i)|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"#{str}#{i == size - 1 ? last\_sep : sep}#{e}"  
> > &nbsp;&nbsp;&nbsp;&nbsp;end[sep.to\_s.length..-1]  
> > &nbsp;&nbsp;end  
> > end

---

<div class="post-metadata">

**Author:** ![Robert\_James](https://avatars.discourse-cdn.com/v4/letter/r/49beb7/32.png) [@Robert\_James](https://rubytalk.org/u/Robert_James)\
**Post date:** [2 January 2007 01:13 UTC](https://rubytalk.org/t/mini-rcr-extra-argument-for-array-join/34127/5 "2007-01-02T01:13:00Z")

</div>

James Gray wrote:

> I've been looking at the to\_sentence() method in Rails. It's  
> basically a join(), but you can give a different final separator. I  
> personally use this kind of functionality often enough to believe it  
> would make a good addition to the core language.

-1  
join is simple to understand and use. It's used in lots of things  
besides English generation. Adding this complicates it and confuses the  
intention.

If you feel to\_sentence() should be made core, put up a RCR for it. But  
let's keep join as join.

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Devin\_Mullins](https://avatars.discourse-cdn.com/v4/letter/d/958977/32.png) [@Devin\_Mullins](https://rubytalk.org/u/Devin_Mullins)\
**Post date:** [31 December 2006 21:30 UTC](https://rubytalk.org/t/mini-rcr-extra-argument-for-array-join/34127/6 "2006-12-31T21:30:50Z")

</div>

Phrogz wrote:

> What makes the final separator so special that it deserves inclusion,  
> while making no allowance for a pre-separator? Just the English  
> language?

Well, just for poops and giggles, here's a less racist alternative (JEG-compatible):

require "enumerator"

class Array  
&nbsp;&nbsp;&nbsp;alias old\_join join  
&nbsp;&nbsp;&nbsp;def join(sep = $, last\_sep = nil, &each\_prefix)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;each\_prefix ||= proc do |e,i|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(last\_sep if i == length - 1) || sep  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;enum\_with\_index.map do |e,i|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i == 0 ? e : "#{each\_prefix[e,i]}#{e}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end.old\_join  
&nbsp;&nbsp;&nbsp;end  
end

if \_\_FILE\_\_ == $PROGRAM\_NAME  
&nbsp;&nbsp;&nbsp;require "test/unit"

&nbsp;&nbsp;&nbsp;class TestJoin \< Test::Unit::TestCase  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def test\_old\_matches\_new  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal(.old\_join, .join)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal([1].old\_join, [1].join)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal([1, 2].old\_join, [1, 2].join)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal((1..5).to\_a.old\_join, (1..5).to\_a.join)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal(.old\_join("|"), .join("|"))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal([1].old\_join("|"), [1].join("|"))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal([1, 2].old\_join("|"), [1, 2].join("|"))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal((1..5).to\_a.old\_join("|"), (1..5).to\_a.join("|"))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def test\_new\_last\_arg\_behavior  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal("1, 2, 3, 4, and 5", (1..5).to\_a.join(", ", ", and "))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal("1, 2, 3, 4 and 5", (1..5).to\_a.join(", ", " and "))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal("1, 2, 3, 4 & 5", (1..5).to\_a.join(", ", " & "))

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal([1, 2].join(","), [1, 2].join("ignored", ","))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def test\_new\_block\_behavior  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal '1 dna, 2, 3, 4, 5',  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(1..5).to\_a.join {|e,i| i == 1 ? ' dna, ' : ', ' }  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;end  
end

---

<div class="post-metadata">

**Author:** ![James\_Edward\_Gray\_II](https://avatars.discourse-cdn.com/v4/letter/j/ea5d25/32.png) [@James\_Edward\_Gray\_II](https://rubytalk.org/u/James_Edward_Gray_II)\
**Post date:** [31 December 2006 22:22 UTC](https://rubytalk.org/t/mini-rcr-extra-argument-for-array-join/34127/7 "2006-12-31T22:22:24Z")

</div>

This was intended as a point of discussion, not my final offer as the ideal implementation. Thank you for cleaning it up though.

James Edward Gray II

> **···**
>
> On Dec 31, 2006, at 4:16 PM, Ryan Davis wrote:
> 
> > On Dec 31, 2006, at 12:05 PM, James Edward Gray II wrote:
> > 
> > > I've been looking at the to\_sentence() method in Rails. It's basically a join(), but you can give a different final separator. I personally use this kind of functionality often enough to believe it would make a good addition to the core language.
> > > 
> > > Even better, I think we can make join() smart enough to eliminate any need for to\_sentence() by adding a second argument. Here's a sample implementation:
> > > 
> > > #!/usr/bin/env ruby -w
> > > 
> > > require "enumerator"
> > > 
> > > class Array  
> > > &nbsp;&nbsp;alias\_method :old\_join, :join  
> > > &nbsp;&nbsp;def join(sep = $, last\_sep = sep)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;return "" if empty?  
> > > &nbsp;&nbsp;&nbsp;&nbsp;enum\_with\_index.inject("") do |str, (e, i)|  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"#{str}#{i == size - 1 ? last\_sep : sep}#{e}"  
> > > &nbsp;&nbsp;&nbsp;&nbsp;end[sep.to\_s.length..-1]  
> > > &nbsp;&nbsp;end  
> > > end
> > 
> > problems:
> > 
> > 1) calculating a static value inside a loop. (only costs about a hundredth of a second for 10k)  
> > 2) iterating when 1/2 of your values are completely static.  
> > 3) being clever by using enumerator.

---

<div class="post-metadata">

**Author:** ![7rans](https://avatars.discourse-cdn.com/v4/letter/7/a8b319/32.png) [@7rans](https://rubytalk.org/u/7rans)\
**Post date:** [1 January 2007 16:40 UTC](https://rubytalk.org/t/mini-rcr-extra-argument-for-array-join/34127/8 "2007-01-01T16:40:06Z")

</div>

Ryan Davis wrote:

> class Array  
> &nbsp;&nbsp;&nbsp;alias\_method :old\_join, :join  
> &nbsp;&nbsp;&nbsp;def join(sep = $, last\_sep = sep)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return "" if empty?
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;seperators = Array.new(size-1, sep)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;seperators[-1] = last\_sep unless seperators.empty?  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.zip(seperators).old\_join  
> &nbsp;&nbsp;&nbsp;end  
> end
> 
> # of iterations = 1000000  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user system total real  
> null\_time 0.140000 0.000000 0.140000 ( 0.140482)  
> jeg 29.690000 0.080000 29.770000 ( 30.144816)  
> ryan 19.780000 0.050000 19.830000 ( 19.998077)

I wonder how this would fair.

&nbsp;&nbsp;class Array  
&nbsp;&nbsp;&nbsp;&nbsp;alias :old\_join :join  
&nbsp;&nbsp;&nbsp;&nbsp;def join( sep=$, last\_sep=nil )  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s = old\_join(sep)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if last\_sep  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rsep = Regexp.escape(sep.to\_s)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rlast = Regexp.escape(last.to\_s)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s.sub!(/#{rsep}#{rlast}$/,"#{last\_sep}#{last}")  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return s  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end

Sorry, the bencmark script wasn't posted and I didn't feel like  
recreating it.

T.

---

<div class="post-metadata">

**Author:** ![Greg\_Brown1](https://avatars.discourse-cdn.com/v4/letter/g/258eb7/32.png) [@Greg\_Brown1](https://rubytalk.org/u/Greg_Brown1)\
**Post date:** [31 December 2006 21:38 UTC](https://rubytalk.org/t/mini-rcr-extra-argument-for-array-join/34127/9 "2006-12-31T21:38:02Z")

</div>

Hmm... this seems powerful and generally useful.

> **···**
>
> On 12/31/06, Devin Mullins \<twifkak@comcast.net\> wrote:
> 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def test\_new\_block\_behavior  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal '1 dna, 2, 3, 4, 5',  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(1..5).to\_a.join {|e,i| i == 1 ? ' dna, ' : ', ' }  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

---

<div class="post-metadata">

**Author:** ![Ryan\_Davis1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/ryan_davis1/32/1848_2.png) [@Ryan\_Davis1](https://rubytalk.org/u/Ryan_Davis1)\
**Post date:** [3 January 2007 02:33 UTC](https://rubytalk.org/t/mini-rcr-extra-argument-for-array-join/34127/10 "2007-01-03T02:33:35Z")

</div>

% ./blah.rb 1\_000\_000  
# of iterations = 1000000  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user system total real  
null\_time 0.140000 0.000000 0.140000 ( 0.139480)  
ryan 19.760000 0.020000 19.780000 ( 19.810269)  
trans 21.290000 0.040000 21.330000 ( 21.398592)  
Loaded suite ./blah  
Started  
....  
Finished in 0.001109 seconds.

4 tests, 24 assertions, 0 failures, 0 errors

> **···**
>
> On Jan 1, 2007, at 8:40 AM, Trans wrote:
> 
> > I wonder how this would fair.
> > 
> > &nbsp;&nbsp;class Array  
> > &nbsp;&nbsp;&nbsp;&nbsp;alias :old\_join :join  
> > &nbsp;&nbsp;&nbsp;&nbsp;def join( sep=$, last\_sep=nil )  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s = old\_join(sep)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if last\_sep  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rsep = Regexp.escape(sep.to\_s)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rlast = Regexp.escape(last.to\_s)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s.sub!(/#{rsep}#{rlast}$/,"#{last\_sep}#{last}")  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return s  
> > &nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;end
> > 
> > Sorry, the bencmark script wasn't posted and I didn't feel like  
> > recreating it.

---

<div class="post-metadata">

**Author:** ![7rans](https://avatars.discourse-cdn.com/v4/letter/7/a8b319/32.png) [@7rans](https://rubytalk.org/u/7rans)\
**Post date:** [3 January 2007 03:43 UTC](https://rubytalk.org/t/mini-rcr-extra-argument-for-array-join/34127/11 "2007-01-03T03:43:20Z")

</div>

Ryan Davis wrote:

> \> I wonder how this would fair.  
> \>  
> \> class Array  
> \> alias :old\_join :join  
> \> def join( sep=$, last\_sep=nil )  
> \> s = old\_join(sep)  
> \> if last\_sep  
> \> rsep = Regexp.escape(sep.to\_s)  
> \> rlast = Regexp.escape(last.to\_s)  
> \> s.sub!(/#{rsep}#{rlast}$/,"#{last\_sep}#{last}")  
> \> end  
> \> return s  
> \> end  
> \> end  
> \>  
> \> Sorry, the bencmark script wasn't posted and I didn't feel like  
> \> recreating it.
> 
> % ./blah.rb 1\_000\_000  
> # of iterations = 1000000  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user system total real  
> null\_time 0.140000 0.000000 0.140000 ( 0.139480)  
> ryan 19.760000 0.020000 19.780000 ( 19.810269)  
> trans 21.290000 0.040000 21.330000 ( 21.398592)  
> Loaded suite ./blah  
> Started  
> ....  
> Finished in 0.001109 seconds.
> 
> 4 tests, 24 assertions, 0 failures, 0 errors

Eek. That was worse then I thought it would be. Thanks for showing me  
though, Ryan.

Of course now that I'm looking at it again I'm wondering how we missed:

&nbsp;&nbsp;class Array  
&nbsp;&nbsp;&nbsp;&nbsp;def join( sep=$, last\_sep=nil )  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return old\_join(sep) unless last\_sep  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[slice(0...-1).old\_join(sep), last].old\_join(last\_sep)  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end

That must to be faster.

T.

> **···**
>
> > On Jan 1, 2007, at 8:40 AM, Trans wrote:

---

<div class="post-metadata">

**Author:** ![Forum](https://avatars.discourse-cdn.com/v4/letter/f/43a26b/32.png) [@Forum](https://rubytalk.org/u/Forum)\
**Post date:** [3 January 2007 10:24 UTC](https://rubytalk.org/t/mini-rcr-extra-argument-for-array-join/34127/12 "2007-01-03T10:24:28Z")

</div>

> Ryan Davis wrote:  
> \>  
> \> \> I wonder how this would fair.  
> \> \>  
> \> \> class Array  
> \> \> alias :old\_join :join  
> \> \> def join( sep=$, last\_sep=nil )  
> \> \> s = old\_join(sep)  
> \> \> if last\_sep  
> \> \> rsep = Regexp.escape(sep.to\_s)  
> \> \> rlast = Regexp.escape(last.to\_s)  
> \> \> s.sub!(/#{rsep}#{rlast}$/,"#{last\_sep}#{last}")  
> \> \> end  
> \> \> return s  
> \> \> end  
> \> \> end  
> \> \>  
> \> \> Sorry, the bencmark script wasn't posted and I didn't feel like  
> \> \> recreating it.  
> \>  
> \> % ./blah.rb 1\_000\_000  
> \> # of iterations = 1000000  
> \> user system total real  
> \> null\_time 0.140000 0.000000 0.140000 ( 0.139480)  
> \> ryan 19.760000 0.020000 19.780000 ( 19.810269)  
> \> trans 21.290000 0.040000 21.330000 ( 21.398592)  
> \> Loaded suite ./blah  
> \> Started  
> \> ....  
> \> Finished in 0.001109 seconds.  
> \>  
> \> 4 tests, 24 assertions, 0 failures, 0 errors
> 
> Eek. That was worse then I thought it would be. Thanks for showing me  
> though, Ryan.
> 
> Of course now that I'm looking at it again I'm wondering how we missed:
> 
> &nbsp;&nbsp;class Array  
> &nbsp;&nbsp;&nbsp;&nbsp;def join( sep=$, last\_sep=nil )  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return old\_join(sep) unless last\_sep  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[slice(0...-1).old\_join(sep), last].old\_join(last\_sep)

slice(0..-2).old\_join(sep) \<\< last\_sep \<\< last.to\_s  
or maybe  
"#{slice(0..-2).old\_join(sep)}#{last\_sep}#{last}"

I like your approach of using old\_join again, it seems so abstraction based,  
but as we are looking for performance 😉

&nbsp;&nbsp;&nbsp;&nbsp;end

> &nbsp;&nbsp;end
> 
> That must to be faster.
> 
> T.

Robert

> **···**
>
> On 1/3/07, Trans \<transfire@gmail.com\> wrote:
> 
> > \> On Jan 1, 2007, at 8:40 AM, Trans wrote:
> 
> --  
> "The real romance is out ahead and yet to come. The computer revolution  
> hasn't started yet. Don't be misled by the enormous flow of money into bad  
> defacto standards for unsophisticated buyers using poor adaptations of  
> incomplete ideas."
> 
> - Alan Kay

---

<div class="post-metadata">

**Author:** ![Forum](https://avatars.discourse-cdn.com/v4/letter/f/43a26b/32.png) [@Forum](https://rubytalk.org/u/Forum)\
**Post date:** [3 January 2007 11:11 UTC](https://rubytalk.org/t/mini-rcr-extra-argument-for-array-join/34127/13 "2007-01-03T11:11:26Z")

</div>

I got so taken away by optimizing, I missed my point!  
I feel that #join should be left alone, if a more powerful  
String#\<something\> is to be needed maybe it would be better to call it  
\<something\> than I feel too that having a prefix or postfix join available.  
A \*strange\* syntax would be possible (that's why it is not good, but I love  
it)  
def \<something\> sep=$, joins={}

list = %{Something blue smth new smth borrowed}  
list.something( ', ' -2 =\> "and" ) =\> "Something, blue, smth, new, smth and  
borrowed"  
list.something( ', ' 0 =\> "{", -1 =\> "}" ) =\> "{Something, blue, smth, new,  
smth, borrowed}"

now that is nonesense of course and might not work in 1.9/2.0???  
let us be reasonable

list.something(:sep =\> ", ", :odd =\> "") =\> "Something blue, smth new, smth  
borrowed"  
list.something(:sep =\> ", ", :odd =\> "", :last\_even =\> "and" ) =\>  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Something blue, smth new and smth borrowed"  
and in full form we would have  
(0..9).something( :pre =\> "\<", :suff =\> "\>", :even =\> "\_", :odd =\> "-",  
:index =\> [5, "\*"] ) =\>  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"\<0-1\_2-3\_4\*5\_6-7\_8-9\>"

That all still might be nonsense/bloat but I have gone to extremes to show  
why I think it would not be String#join anymore and thus should not be  
called String#join

If OTOH a majority thinks enhancing String#join, what about a block  
enhancement

list.join do  
&nbsp;&nbsp;&nbsp;\>ele, index|  
&nbsp;&nbsp;&nbsp;(index % 2).zero? ? : "," ? "\*" # might be nice to change sep on value of  
ele too.  
end

cheers  
Robert

> **···**
>
> --  
> "The real romance is out ahead and yet to come. The computer revolution  
> hasn't started yet. Don't be misled by the enormous flow of money into bad  
> defacto standards for unsophisticated buyers using poor adaptations of  
> incomplete ideas."
> 
> - Alan Kay

---

<div class="post-metadata">

**Author:** ![7rans](https://avatars.discourse-cdn.com/v4/letter/7/a8b319/32.png) [@7rans](https://rubytalk.org/u/7rans)\
**Post date:** [3 January 2007 16:30 UTC](https://rubytalk.org/t/mini-rcr-extra-argument-for-array-join/34127/14 "2007-01-03T16:30:12Z")

</div>

Robert Dober wrote:

> slice(0..-2).old\_join(sep) \<\< last\_sep \<\< last.to\_s  
> or maybe  
> "#{slice(0..-2).old\_join(sep)}#{last\_sep}#{last}"
> 
> I like your approach of using old\_join again, it seems so abstraction based,

🙂

> but as we are looking for performance 😉

Yep, even better.

I'll credit you and add this to Facets, but I'd rather name it  
something other than #join. Right now I have #join\_sentence, but that's  
rather long. Any suggestions?

And for what it's worth, IMO a block additon to join certainly couldn't  
hurt. In fact it would be quite nice for alternating separators.

&nbsp;&nbsp;hash.to\_a.flatten.join{ |index| index % 2 == 0 ? ':' : "\n" }

Or something like that.

T.

---

<div class="post-metadata">

**Author:** ![Devin\_Mullins](https://avatars.discourse-cdn.com/v4/letter/d/958977/32.png) [@Devin\_Mullins](https://rubytalk.org/u/Devin_Mullins)\
**Post date:** [3 January 2007 15:07 UTC](https://rubytalk.org/t/mini-rcr-extra-argument-for-array-join/34127/15 "2007-01-03T15:07:13Z")

</div>

Robert Dober wrote:

> If OTOH a majority thinks enhancing String#join, what about a block  
> enhancement

Dude... read the whole thread. You're not killfiling me, too, are you?

Not that I'm a fan of the block form... if join gets augmented, it should be something fairly simple and 80/20, such as last\_sep.

Devin

---

<div class="post-metadata">

**Author:** ![Forum](https://avatars.discourse-cdn.com/v4/letter/f/43a26b/32.png) [@Forum](https://rubytalk.org/u/Forum)\
**Post date:** [3 January 2007 16:48 UTC](https://rubytalk.org/t/mini-rcr-extra-argument-for-array-join/34127/16 "2007-01-03T16:48:06Z")

</div>

> Robert Dober wrote:  
> \> slice(0..-2).old\_join(sep) \<\< last\_sep \<\< last.to\_s  
> \> or maybe  
> \> "#{slice(0..-2).old\_join(sep)}#{last\_sep}#{last}"  
> \>  
> \> I like your approach of using old\_join again, it seems so abstraction  
> based,
> 
> 🙂
> 
> \> but as we are looking for performance 😉
> 
> Yep, even better.
> 
> I'll credit you and add this to Facets, but I'd rather name it  
> something other than #join. Right now I have #join\_sentence, but that's  
> rather long. Any suggestions?
> 
> And for what it's worth, IMO a block additon to join certainly couldn't  
> hurt. In fact it would be quite nice for alternating separators.
> 
> &nbsp;&nbsp;hash.to\_a.flatten.join{ |index| index % 2 == 0 ? ':' : "\n" }
> 
> Or something like that.

I am flattered , thx 🙂 concerning the block I have to admit that Devin has  
come up with that idea early in the thread already!  
Cheers  
Robert

T.

> **···**
>
> On 1/3/07, Trans \<transfire@gmail.com\> wrote:
> 
> > 
> 
> --  
> "The real romance is out ahead and yet to come. The computer revolution  
> hasn't started yet. Don't be misled by the enormous flow of money into bad  
> defacto standards for unsophisticated buyers using poor adaptations of  
> incomplete ideas."
> 
> - Alan Kay

---

<div class="post-metadata">

**Author:** ![Forum](https://avatars.discourse-cdn.com/v4/letter/f/43a26b/32.png) [@Forum](https://rubytalk.org/u/Forum)\
**Post date:** [3 January 2007 15:14 UTC](https://rubytalk.org/t/mini-rcr-extra-argument-for-array-join/34127/17 "2007-01-03T15:14:34Z")

</div>

> Robert Dober wrote:  
> \> If OTOH a majority thinks enhancing String#join, what about a block  
> \> enhancement  
> Dude... read the whole thread. You're not killfiling me, too, are you?

No I am not, just got taken away by hacking Ruby, very nice that code of  
yours 😉

Not that I'm a fan of the block form... if join gets augmented, it

> should be something fairly simple and 80/20, such as last\_sep.
> 
> Devin

Robert  
BTW I was called Mr. Dober and Dude recently, is there something wrong with  
my name? 😉

> **···**
>
> On 1/3/07, Devin Mullins \<twifkak@comcast.net\> wrote:  
> --  
> "The real romance is out ahead and yet to come. The computer revolution  
> hasn't started yet. Don't be misled by the enormous flow of money into bad  
> defacto standards for unsophisticated buyers using poor adaptations of  
> incomplete ideas."
> 
> - Alan Kay
