Skip to content

Commit

Permalink
Refactor Object#try to use inheritance. [#1774 state:resolved]
Browse files Browse the repository at this point in the history
Signed-off-by: Pratik Naik <pratiknaik@gmail.com>
  • Loading branch information
joshsusser authored and lifo committed Jan 18, 2009
1 parent 3b1cd9e commit 78f2c19
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 17 deletions.
17 changes: 0 additions & 17 deletions activesupport/lib/active_support/core_ext/object/misc.rb
Expand Up @@ -87,21 +87,4 @@ def acts_like?(duck)
respond_to? "acts_like_#{duck}?" respond_to? "acts_like_#{duck}?"
end end


# Tries to send the method only if object responds to it. Return +nil+ otherwise.
# It will also forward any arguments and/or block like Object#send does.
#
# ==== Example :
#
# # Without try
# @person ? @person.name : nil
#
# With try
# @person.try(:name)
#
# # try also accepts arguments/blocks for the method it is trying
# Person.try(:find, 1)
# @people.try(:map) {|p| p.name}
def try(method, *args, &block)
send(method, *args, &block) unless self.nil?
end
end end
30 changes: 30 additions & 0 deletions activesupport/lib/active_support/core_ext/try.rb
@@ -0,0 +1,30 @@
class Object
# Tries to send the method only if object responds to it. Return +nil+ otherwise.
# It will also forward any arguments and/or block like Object#send does.
#
# ==== Examples
#
# Without try
# @person && @person.name
# or
# @person ? @person.name : nil
#
# With try
# @person.try(:name)
#
# Try also accepts arguments/blocks for the method it is trying
# Person.try(:find, 1)
# @people.try(:collect) {|p| p.name}
#--
# This method def is for rdoc only. The alias_method below overrides it as an optimization.
def try(method, *args, &block)
send(method, *args, &block)
end
alias_method :try, :__send__
end

class NilClass
def try(*args)
nil
end
end

6 comments on commit 78f2c19

@christos
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn’t the method name and the documentation a bit misleading?

Tries to send the method only if object responds to it. Return nil otherwise.

It would seem that it only works if the object is nil OR responds to the method.

>> @person = "Bob"
>> @person.try(:name) # would have expected nil as object dosen't respond to name
NoMethodError: undefined method `name' for "Bob":String

My understanding of it is that it should replace this idiomatic Ruby:

@person && @person.name || 'No name'

with this

@person.try(:name) || 'No name'
 

…as first described here: http://ozmm.org/posts/try.html

@dstrelau
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

christos: that's how @#try used to behave. See this commit and this post for the background.

@christos
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough. The docs are still not clear though:

Tries to send the method only if object responds to it. Return nil otherwise.

If the method doesn’t respond to the method, it raises NoMethodError

Shouldn’t that be documented?

@lifo
Copy link
Member

@lifo lifo commented on 78f2c19 Jan 24, 2009

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Christos : Yeah looks like the doc need fixing. I’ve added you to docrails. So maybe you can make that happen :) Just push the doc fix to the docrails branch and it’ll be merged with the rails/master soon.

@christos
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pratik: Fixed at http://github.com/lifo/docrails/commit/929088189de1d189c643246a491ba8fb5347b1d3

@lifo
Copy link
Member

@lifo lifo commented on 78f2c19 Jan 26, 2009

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey Chris,

Thanks. I had reverted that commit and applied it with some changes.

Please sign in to comment.