Skip to content

Instantly share code, notes, and snippets.

@mrship
Created May 6, 2014 09:37
Show Gist options
  • Select an option

  • Save mrship/d0a3c50863856f3eb426 to your computer and use it in GitHub Desktop.

Select an option

Save mrship/d0a3c50863856f3eb426 to your computer and use it in GitHub Desktop.

try vs andand vs early return (x2)

Which is the preferred way to determine if a chained call is nil? i.e:

  1. company.andand.name
  2. company.try(:name)
  3. return nil if company.nil?; company.name
  4. (company or return nil).name

For the last one, you must use the predicate or rather than || to make the return work correctly.

@dncrht
Copy link
Copy Markdown

dncrht commented May 6, 2014

The webapp is full of company.andand.name but it seems we tend to favour company.try(:name) lately.
However, abusing and chaining .try is a code smell: something is wrong way up

@mezis
Copy link
Copy Markdown

mezis commented May 6, 2014

4- Absolutely not. Too error prone.
3- I'd favour in cases where one can return early (which one should IMO)
1- Is typical in our monorail code base.

IMHO I'd usually try to be idiomatic, unless andand actually reads well and shortens the syntax.

If there is a default, I prefer:

company.present? ? company.name : 'no company'

(which is also faster) to:

company.andand.name || 'no company'

If there isn't and returning nil is fine,

company.andand.name

I would not use try since the semantics are different — if company is not nil but doesnt not respond to #name you actually want an exception to be raised.

@mezis
Copy link
Copy Markdown

mezis commented May 6, 2014

Again, to emphasise: try has very different semantics, and is not what you want here.
(try tests respond_to?, not if the recipient of the message is nil, which is possibly why andand exists in the first place).

@tadejm
Copy link
Copy Markdown

tadejm commented May 6, 2014

I like version 3 because is explicit and does not have any dependencies. Version 2 is also acceptable.

@mrship
Copy link
Copy Markdown
Author

mrship commented May 6, 2014

Seems #4 is certainly out though. Shame, I like that one!

@nas
Copy link
Copy Markdown

nas commented May 6, 2014

3 or company.present? ? company.name : 'no company'

@krisleech
Copy link
Copy Markdown

try is also slightly different in Rails 3 and 4. I'll try and find out why unless someone knows...

@amencarini
Copy link
Copy Markdown

# Rails 4
public_send(*a, &b) if respond_to?(a.first)
# Rails 3
__send__(*a, &b)

From what I gather in Rails 4 it can hide calling a method on the wrong type rather than nil alone.

@joaomilho
Copy link
Copy Markdown

class NullCompany
  def name
    'no company'
  end
end

company = some_logic? ? Company.new(some_data) : NullCompany
company.name

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment