aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib/active_support/core_ext/object/try.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport/lib/active_support/core_ext/object/try.rb')
-rw-r--r--activesupport/lib/active_support/core_ext/object/try.rb31
1 files changed, 24 insertions, 7 deletions
diff --git a/activesupport/lib/active_support/core_ext/object/try.rb b/activesupport/lib/active_support/core_ext/object/try.rb
index 09b8a19789..56da398978 100644
--- a/activesupport/lib/active_support/core_ext/object/try.rb
+++ b/activesupport/lib/active_support/core_ext/object/try.rb
@@ -9,7 +9,23 @@ class Object
#
# instead of
#
- # @person ? @person.name : nil
+ # @person.name if @person
+ #
+ # +try+ calls can be chained:
+ #
+ # @person.try(:spouse).try(:name)
+ #
+ # instead of
+ #
+ # @person.spouse.name if @person && @person.spouse
+ #
+ # +try+ will also return +nil+ if the receiver does not respond to the method:
+ #
+ # @person.try(:non_existing_method) #=> nil
+ #
+ # instead of
+ #
+ # @person.non_existing_method if @person.respond_to?(:non_existing_method) #=> nil
#
# +try+ returns +nil+ when called on +nil+ regardless of whether it responds
# to the method:
@@ -24,7 +40,7 @@ class Object
#
# The number of arguments in the signature must match. If the object responds
# to the method the call is attempted and +ArgumentError+ is still raised
- # otherwise.
+ # in case of argument mismatch.
#
# If +try+ is called without arguments it yields the receiver to a given
# block unless it is +nil+:
@@ -38,17 +54,18 @@ class Object
#
# @person.try { upcase.truncate(50) }
#
- # Please also note that +try+ is defined on +Object+, therefore it won't work
+ # Please also note that +try+ is defined on +Object+. Therefore, it won't work
# with instances of classes that do not have +Object+ among their ancestors,
# like direct subclasses of +BasicObject+. For example, using +try+ with
# +SimpleDelegator+ will delegate +try+ to the target instead of calling it on
- # delegator itself.
+ # the delegator itself.
def try(*a, &b)
try!(*a, &b) if a.empty? || respond_to?(a.first)
end
- # Same as #try, but will raise a NoMethodError exception if the receiving is not nil and
+ # Same as #try, but will raise a NoMethodError exception if the receiver is not +nil+ and
# does not implement the tried method.
+
def try!(*a, &b)
if a.empty? && block_given?
if b.arity.zero?
@@ -64,12 +81,12 @@ end
class NilClass
# Calling +try+ on +nil+ always returns +nil+.
- # It becomes specially helpful when navigating through associations that may return +nil+.
+ # It becomes especially helpful when navigating through associations that may return +nil+.
#
# nil.try(:name) # => nil
#
# Without +try+
- # @person && !@person.children.blank? && @person.children.first.name
+ # @person && @person.children.any? && @person.children.first.name
#
# With +try+
# @person.try(:children).try(:first).try(:name)