Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Super.tap {} - what does it do and use cases?

Tags:

ruby

I came across this construction in a gem and don't understand the intent. I know what tap does alone, but why would someone call super.tap {} instead of just continuing the code normally after the super call.

def my_method
 super.tap do |u|
    if @user && @user.new_record?
      @omniauth = u.session[:session]
      u.session[:omniauth] = nil unless @user.new_record?
    end
  end
end

Can anyone enlighten me?

like image 358
Jack Kinsella Avatar asked Feb 24 '11 11:02

Jack Kinsella


People also ask

What are tap in methods?

tap method. This method allows you to "tap" into the result of a method call, usually to perform additional operations on that result, or to debug that result (i.e. by printing to the console). A quick Google search for ruby tap method will return a lot of articles and StackOverflow discussions about when to use .


2 Answers

tap is used to perform some operations on an object, and then return that object. That sounds confusing, but it's helpful when chaining methods. Example:

def make_a_something
  t = Something.new
  t.method
  t.attr = 'foo'
  t # must remember to manually return t, otherwise 'foo' is returned
end

can be replaced with

def make_a_something
  Something.new.tap do |t|
    t.method
    t.attr = 'foo'
  end
end

If that doesn't strike you as terribly useful, see some further examples here.

like image 70
dmnd Avatar answered Sep 19 '22 16:09

dmnd


super.tap is nothing but tap method called on whatever super returns. User dmnd already explained pretty well what tap does (why the downwote?). super calls the method from the ancestor class which you are overriding.

So, the code you pasted is equivalent with the following:

original_result = super
if @user && @user.new_record?
  @omniauth = original_result.session[:session]
  original_result.session[:omniauth] = nil unless @user.new_record?
end
return original_result

Essentially, super.tap can be used for wrapping the method from the inherited class, adding some functionality, but keeping the result.

like image 42
Mladen Jablanović Avatar answered Sep 17 '22 16:09

Mladen Jablanović