try(*a, &b) public

Invokes the method identified by the symbol method, passing it any arguments and/or the block specified, just like the regular Ruby Object#send does.

Unlike that method however, a NoMethodError exception will not be raised and nil will be returned instead, if the receiving object is a nil object or NilClass.

If try is called without a method to call, it will yield any given block with the object.

Please also note that try is defined on Object, therefore it won’t work with subclasses of BasicObject. For example, using try with SimpleDelegator will delegate try to target instead of calling it on delegator itself.


Without try

@person && @person.name


@person ? @person.name : nil

With try


try also accepts arguments and/or a block, for the method it is trying

Person.try(:find, 1)
@people.try(:collect) {|p| p.name}

Without a method argument try will yield to the block unless the receiver is nil.

@person.try { |p| "#{p.first_name} #{p.last_name}" }
Show source
Register or log in to add new notes.
January 6, 2010
6 thanks

Doesn't return nil if the object you try from isn't nil.

Note that this doesn’t prevent a NoMethodError if you attempt to call a method that doesn’t exist on a valid object.

a = Article.new

a.try(:author) #=> #<Author ...>

nil.try(:doesnt_exist) #=> nil

a.try(:doesnt_exist) #=> NoMethodError: undefined method `doesnt_exist' for #<Article:0x106c7d5d8>

This is on Ruby 1.8.7 patchlevel 174

July 24, 2012
3 thanks

rest of code is in NilClass#try

If you click “Show source” here, you may get confused. The logic for #try is shared between this method and NilClass#try . Both versions are currently implemented in the file activesupport/lib/active_support/core_ext/object/try.rb .

June 10, 2009
2 thanks

[:a, :b, :c].try([1]) ? The answer is No.

Correct way is this:

[:a, :b, :c].try(:at, 1)
August 21, 2014 - (v4.0.2)
2 thanks

In Rails 4 it DOES return nil, even if the object you try from isn't nil

The try method does not raise a NoMethodError if you call a method that doesn’t exist on an object.

a = Article.new

a.try(:author) #=> #<Author ...>

nil.try(:doesnt_exist) #=> nil

a.try(:doesnt_exist) #=> nil


a.try(&:doesnt_exist) #=> Raises NoMethodError
January 6, 2010
1 thank


without using at

[:a, :b, :c].try(:[], 1)
September 13, 2013
1 thank

Edge case

NilClass#try doesn’t check for methods on itself:

nil.blank?        #=> true
nil.try :blank?   #=> nil
February 3, 2015
0 thanks

Poor man's maybe

After creating a simple Maybe monad in Ruby, a colleaque noticed I could have just used try (I wasn’t aware try supports blocks). I think the method was even meant for such cases.

Why I mention this? Because it clarifies the whole ‘raises exception if method does not exist’ thing. It should not be crappy solution to exception handling, but allow for doing away with messy if statements. An example:

report = params[:query_type]
.try { |qt| build_query(qt) }
.try { |sql| run_query(sql) }
.try { |res| format_result(res) }

If any of the expressions params[], build_query, run_query etc. returns nil, the chain is halted and nil is returned. It still throws exceptions if a values is not nil and method does not exist, which is just like it should.