Ruby built-in method to yield self unless nil?

952 views
Skip to first unread message

Steve H

unread,
Jun 13, 2012, 9:01:33 PM6/13/12
to rails-...@googlegroups.com
I'm looking for something built-in to Ruby that works kind of like Object#tap, but only yields if self is not nil.

That is, can I do this without monkey-patching Object?

If it's in Activesupport that's fine too. I feel like this method exists but I can't find it.

class Object
  def tap_unless_nil
    if nil?
      nil
    else
      yield self
    end
  end
end

"hello".tap_unless_nil{ |a| puts "yielded #{a.inspect}" }
nil.tap_unless_nil{ |a| puts "yielded #{a.inspect}" }

Ryan Bigg

unread,
Jun 13, 2012, 9:04:29 PM6/13/12
to rails-...@googlegroups.com
You can use Object#try from ActiveSupport to do this:

"hello".try(:tap) { |a| puts "yielded #{a.inspect}" }
nil.try(:tap) { |a| puts "yielded #{a.inspect}" }

try will attempt a method, but only if it's called on an object that's not nil.
--
You received this message because you are subscribed to the Google Groups "Ruby or Rails Oceania" group.
To view this discussion on the web visit https://groups.google.com/d/msg/rails-oceania/-/XkiiF0QABO0J.
To post to this group, send email to rails-...@googlegroups.com.
To unsubscribe from this group, send email to rails-oceani...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/rails-oceania?hl=en.

Steve Hoeksema

unread,
Jun 13, 2012, 9:06:07 PM6/13/12
to rails-...@googlegroups.com
Aha! Didn't realise try could take a block. Thanks!

Ryan Bigg

unread,
Jun 13, 2012, 9:07:08 PM6/13/12
to rails-...@googlegroups.com
try just takes all arguments to a method an passes them along, including blocks :)

Ben Hoskings

unread,
Jun 13, 2012, 9:09:15 PM6/13/12
to rails-...@googlegroups.com
Well tap already does what you want for everything else, so:

class NilClass
def tap
nil
end
end

I'm not suggesting using this code... just pointing out that it's possible. :)

- Ben

Ben Hoskings

unread,
Jun 13, 2012, 9:16:56 PM6/13/12
to rails-...@googlegroups.com
Also it's worth mentioning that code sample of yours won't do what you expect -- tap always returns its caller, but your method will return the block value for non-nil receivers.

The logic should be:

class Object
def tap_unless_nil
yield(self) unless nil?
self
end
end

Again, wouldn't endorse it, I'm just talkin' hypotheticals here :)

- Ben



On 14/06/2012, at 11:01 AM, Steve H wrote:

Steve Hoeksema

unread,
Jun 13, 2012, 9:21:44 PM6/13/12
to rails-...@googlegroups.com
Cool, I wasn't actually using that code, just threw it together to illustrate what I was after. #try does what I want, so that's handy.
Reply all
Reply to author
Forward
0 new messages