alias_method :tap, :affect

T

Todd Benson

This is the first I've heard of Object#tap. It seems backward because
you almost always want the result of the block, not the object back
again. All of my ruby scripts use

class Object
def as
yield self
end
end

This can be useful in the right context. Should it be canonized in
Ruby? I'm not sure.
platform_audio_files = audio_stems.map { |f|
f + "." + audio_ext[platform]
}.as { |t|
t + audio_basenames
}.map { |f|
File.join(audio_dir, f)
}

This method chaining looks ugly to me, but I'm not a CS guy; so, to
each his own.
I know this could be written

platform_audio_files = (audio_stems.map { |f|
f + "." + audio_ext[platform]
} + audio_basenames).map { |f|
File.join(audio_dir, f)
}

but I find that uncouth compared to the former.

If ruby is adding anything, it should be the behavior of Object#as,
not Object#tap.

You are suggesting that people add something that probably doesn't
need to be added. I'm halfway convinced, but I think you should
present a couple more use cases for me to sway your way (sorry, folks,
for the poetic language :)

Todd
 
P

Peña, Botp

From: furtive
# On Nov 12, 2:31 pm, Martin
# > #tap is the opposite use case - you want to "tap" the object stream,
# > observing without affecting.
# OK I understand Object#tap now. At first I thought the motivation was
# to modify the object inside the block, but now I see that it can be a
# useful part of functional-style ruby.
# So, to throw this out again --- there should also be Object#as which
# returns the block result (I like the name 'as' but I am not
# particularly attached to it). I can personally attest to its
# usefulness, and I can show reams of examples in addition to the above
# one I gave.

(my previous message seems to have lost, so i apologize for a 2nd post)

tap is indispensable for me when it comes to chaining (specially bang =
methods)..

naive example follows...

~> s
=3D> "This is a test"

~> s.capitalize!.capitalize!
NoMethodError: undefined method `capitalize!' for nil:NilClass

breaks!

~> s.upcase!.upcase!
=3D> nil

breaks!

~> s.upcase!.capitalize!
NoMethodError: undefined method `capitalize!' for nil:NilClass

breaks!

~> s.tap(&:upcase!).tap(&:upcase!).tap(&:capitalize!).tap(&:capita
lize!).tap(&:downcase!).tap(&:downcase!)
=3D> "this is a test"

long chain, no break :)

btw, i like the #tap name, it's like tapping a chain so that it wont =
break. (i'm not an english expert but that is how i usually use the =
word)..

kind regards -botp
 
P

Peña, Botp

From: (e-mail address removed) [mailto:[email protected]]=20
# > > This is the first I've heard of Object#tap. It seems=20
# backward because
# > > you almost always want the result of the block, not the=20
# object back
# > > again.
# > #tap is the opposite use case - you want to "tap" the object stream,
# > observing without affecting.
#=20
# OK I understand Object#tap now. At first I thought the motivation was
# to modify the object inside the block, but now I see that it can be a
# useful part of functional-style ruby.

~> s
=3D> "THIS IS A TEST"
~> s.upcase!.capitalize!
NoMethodError: undefined method `capitalize!' for nil:NilClass
...
~> s.tap{|x| x.upcase!}.capitalize!
=3D> "This is a test"
~> s
=3D> "This is a test"

C:\ruby1.9\bin>ri Object#tap -T
------------------------------------------------------------- Object#tap
obj.tap{|x|...} =3D> obj
------------------------------------------------------------------------
Returns the receiver after executing the block given. Its main
purpose is to be inserted in the method chain.

kind regards -botp
The essence of knowledge, is having it, to apply it;..
 
J

James Edward Gray II

I am an English expert and I have no idea what "tap" is supposed to
have to do with what this #tap method does.

It's like "tapping" a call chain, just as you would tap a phone call.

James Edward Gray II
 
P

Peña, Botp

From: David A. Black [mailto:[email protected]]=20
# On Thu, 15 Nov 2007, James Edward Gray II wrote:
# > On Nov 15, 2007, at 7:41 AM, David A. Black wrote:
# >> I am an English expert and I have no idea what "tap" is supposed to
# >> have to do with what this #tap method does.
# > It's like "tapping" a call chain, just as you would tap a phone =
call.
# It's like tapping a phone call after the call is over :)
# David

pardon me sir davide, but i am not sure what you mean there, in my =
examples, i think tap tapped before it called upcase/capitalize, no?

kind regards -botp
 
C

Clifford Heath

filename = File.basename(input.map { |t|
t.gsub(re, "_")
}.join)

filename = input.map { |t|
t.gsub(re, "_")
}.join.as { |t|
File.basename(t)
}

I greatly prefer the latter. I want to chain, chain, chain, and I
don't want pesky prefix-y function calls like File.basename() to cramp
my style.

It wasn't entirely a coincidence that JEGII found concat - it's
the sort of thing that is often needed with arrays. The underlying
problem in your example is that filename operations aren't object-
oriented, so you wind up using a method-call on a class... yuk.

This is a weakness in the standard classes - there should be a
Filename class, and a String#to_filename method, so your example
becomes:

filename = input.map { |t|
t.gsub(re, "_")
}.join.to_filename.base

No need for Object#as in that. There are other use cases of course,
and I also might use "as" sometimes myself.

Clifford Heath.
 
M

Marc Heiler

Not sure that I am able to contribue to this discussion, but I must
admit neither .tap nor .affect are very intuitive for me on first glance
:)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top