ActiveSupport 4.0.0 defines two try
methods: one is for Object
instances:
class Object
def try(*a, &b)
if a.empty? && block_given?
yield self
else
public_send(*a, &b) if respond_to?(a.first)
end
end
end
the other is for NilClass
instances (nil
objects):
class NilClass
def try(*args)
nil
end
end
Now, suppose we have an Object
instance (excluding nil
, which actually inherits from Object
, like everything else in Ruby), defining a method which returns nil
:
class Test
def returns_nil
nil
end
end
So, running Test.new.try(:returns_nil)
or Test.new.not_existing_method
, Object#try
will be called, which will check if a public method exists (the respond_to?
); if it does it will call the method (the public_send)
, else it will return nil
(there aren't other lines).
If we call another try
on of these returning nil
methods:
Test.new.try(:returns_nil).try(:any_other_method)
Test.new.try(:not_existing_method).try(:any_other_method)
we will call NilClass#try
, which is nil#try
, which simply ignores everything and returns nil
. So any other try
will be called on a nil
instance and return nil
.