Jay
Jay

Reputation: 237

Better alternative to try(:output).try(:data).try(:name)?

"output" is a serialized OpenStruct.

def title
  try(:output).try(:data).try(:title)
end

What would be better? :)

Upvotes: 6

Views: 1871

Answers (4)

Olalekan Sogunle
Olalekan Sogunle

Reputation: 2357

Referring to this blog you might find it better to use the &. operator like below for ruby version > 2.3.0;

 output&.data&.title

Upvotes: 5

Benjamin Curtis
Benjamin Curtis

Reputation: 1660

Or simply this:

def title
  output.data.title rescue nil
end

Upvotes: 4

Alessandra Pereyra
Alessandra Pereyra

Reputation: 2640

Thoughtbot just talked about this on their blog, using what they call it's a Shallow Nil:

def swallow_nil
  yield
rescue NoMethodError
  nil
end

So, in their example, they could do something like:

campaign = swallow_nil { supporter.politician.campaign }

Or, in your case,

def title
  swallow_nil { output.data.title }
end

However, be aware that any of your bugs will also be swallowed and would be hard to find, specially since it traps every NoMethodErrors, which would be caused from other parts of your code (although if you use testing, this helps a lot).

Another approach would be to use andand, where your code would be then

def title
  output.andand.data.andand.title
end

Not as clean as the swallow_nil one, but probably best to not just ignore everything.

Upvotes: 1

hgmnz
hgmnz

Reputation: 13306

def try_chain
  yield
rescue NoMethodError
  nil
end

def title
  try_chain { output.data.title }
end

Upvotes: 1

Related Questions