# Object#tap (was Nice algorithm for 'spreading' indexes across an array?)

**URL:** <https://www.ruby-forum.com/t/object-tap-was-nice-algorithm-for-spreading-indexes-across-an-array/192339>\
**Category:** Ruby\
**Created:** [July 28, 2010, 4:03pm UTC](https://www.ruby-forum.com/t/object-tap-was-nice-algorithm-for-spreading-indexes-across-an-array/192339 "2010-07-28T16:03:44Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![duffbeer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ec9cab/32.png) [@duffbeer](https://www.ruby-forum.com/u/duffbeer)\
**Post date:** [July 28, 2010, 4:03pm UTC](https://www.ruby-forum.com/t/object-tap-was-nice-algorithm-for-spreading-indexes-across-an-array/192339/1 "2010-07-28T16:03:44Z")

</div>

On Wed, Sep 2, 2009 at 1:41 AM, Max  
Williams[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > > arr = (1…12).to\_a  
> > > It feels like there should be a simple solution for this but i can’t  
> > > think of a nice way. Anyone?
> 
> thanks  
> max

Thanks to a post by David M. in a recent thread, I learned about  
Object#tap.  
He used it on a hash.

I’ve used it here on an array.  
Is there any problem using Object#tap in this way?  
I saw some examples, but in the examples the object was not modified  
in the block.

class Array  
def spread(n)  
dup.tap{|a| (size-n).downto(1).map{|b| size\*b/(size-n+1)}.each{|c|  
a.delete\_at(c)}}  
end  
end

arr = (1…12).to\_a  
(3…12).each{|t| p arr.spread(t)}

###Output

[1, 6, 12]  
[1, 4, 8, 12]  
[1, 3, 6, 9, 12]  
[1, 3, 5, 8, 10, 12]  
[1, 2, 4, 6, 8, 10, 12]  
[1, 2, 4, 6, 7, 9, 11, 12]  
[1, 2, 3, 5, 6, 8, 9, 11, 12]  
[1, 2, 3, 4, 6, 7, 8, 10, 11, 12]  
[1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12]  
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

Harry

---

<div class="post-metadata">

**Author:** ![duffbeer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ec9cab/32.png) [@duffbeer](https://www.ruby-forum.com/u/duffbeer)\
**Post date:** [July 29, 2010, 5:00am UTC](https://www.ruby-forum.com/t/object-tap-was-nice-algorithm-for-spreading-indexes-across-an-array/192339/2 "2010-07-29T05:00:35Z")

</div>

On Wednesday, July 28, 2010 09:03:18 am Harry K. wrote:

> Is there any problem using Object#tap in this way?  
> I saw some examples, but in the examples the object was not modified  
> in the block.

Oh, you mean modifying the array?

> class Array  
> def spread(n)  
> dup.tap{|a| (size-n).downto(1).map{|b| size\*b/(size-n+1)}.each{|c|  
> a.delete\_at©}}  
> end  
> end

Not particularly. The thing you have to be careful of is reassigning it  
– for  
example, this wouldn’t work:

1.tap {|x| x+=1}

You have to actually modify the object. For example, if we’re talking  
about  
arrays, instead of this:

string.tap {|x| x + ‘foo’}

Do this:

string.tap {|x| x \<\< ‘foo’}

It seems like \<\< returns self, so that’s completely unnecessary, you  
could  
just do this:

(string \<\< ‘foo’)

…but hopefully it illustrates the point.

I have a feeling I’m overcomplicating things, though. Here’s one  
possible  
implementation of Object#tap:

class Object  
def tap  
yield self  
self  
end  
end

Nothing mysterious about it at all. (MRI might do it in C, I’m not sure,  
but  
the above works.)

---

<div class="post-metadata">

**Author:** ![duffbeer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ec9cab/32.png) [@duffbeer](https://www.ruby-forum.com/u/duffbeer)\
**Post date:** [July 29, 2010, 6:50am UTC](https://www.ruby-forum.com/t/object-tap-was-nice-algorithm-for-spreading-indexes-across-an-array/192339/3 "2010-07-29T06:50:38Z")

</div>

On Thu, Jul 29, 2010 at 12:40 PM, David M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> Do this:
> 
> string.tap {|x| x \<\< ‘foo’}

A nice use of #tap (IMO, and these things are very much a matter of  
opinion):

message = String.new.tap { |s|  
s \<\< “…”  
s \<\< “…”  
if some\_condition?  
s \<\< “…”  
else  
s \<\< “…”  
end  
end

Gavin
