Ricman R
Ricman R

Reputation: 13

Ruby quirk: Using 'return' to get a nil value

I am doing a problem at Rubymonk where I have to test if an array is 'nil' before doing an operation (adding items inside a nested array but that is not really relevant to the question). I notice, however, if I enter an empty array:

ary.nil? ? nil : ary.map {|x,y=0| x + y }

The code returns 'nil' as desired, but if I do

ary.nil? ? return nil : ary.map {|x,y=0| x + y }

it no longer works.

However, if I do

if ary.nil?
   return nil
 else
   ary.map {|x,y=0| x + y }
 end

the code works as expected and again returns 'nil'.

Why does return nil work in the last instance but not in the ternary expression?

I would have expected the expression return nil to work in both instances.

UPDATE: Thank you @ShadowRanger. Using parentheses in the ternary addresses my concern. Much appreciated!

ary.nil? ? (return nil) : ary.map {|x,y=0| x + y }

Upvotes: -1

Views: 101

Answers (2)

Ricman R
Ricman R

Reputation: 13

Answer provided by 'ShadowRanger' in comments. Placing here for visibility

"Looks like your ternary works if you just use plain return (which returns nil when not given an argument). As does (return nil). Guessing it's an issue with the grammar not allowing return and a value in the middle of a ternary conditional expression like that without parentheses. Ruby's grammar is rather ad hoc at times (it's amazing how often spaces matter, relative to most other languages), this doesn't really surprise me"

Upvotes: 0

Chris
Chris

Reputation: 36620

return doesn't make much sense inside of an expression like that, and in fact cannot be used in this place. You may want to return explicitly before you do the map:

def foo(ary)
  return nil if ary.nil?
  ary.map { |x| x + 1 }
end

Or the more sensible way to solve this is just to use the safe navigation operator, which will yield nil if ary is nil.

def foo(ary)
  ary&.map { |x| x + 1 }
end

Upvotes: 2

Related Questions