dace
dace

Reputation: 6363

Unexpected return error in Ruby

I'm new to learning Ruby and am having a little trouble with nested structures.

What I'm trying to do is return :last name ("Doe") if the value of :first is "John":

people = {
  :family => [
    {:first => "John", :last => "Doe"},
    {:first => "Jane", :last => "Smith"}
  ]
}

people[:family].each {|index| return index[:last] if index[:first] == "John"}

However, the console is giving me this error:

test.rb:8:in `block in <main>': unexpected return (LocalJumpError)
from test.rb:8:in `each'
from test.rb:8:in `<main>'

When I test this in the console and replace 'return' with 'puts', it gives me back "Doe" but for some reason the 'return' seems to be causing the 'unexpected return (LocalJumpError)'. How can I successfully return this value without running into this error?

Thanks - any and all help is greatly appreciated!

Upvotes: 0

Views: 1096

Answers (4)

Anton Harniakou
Anton Harniakou

Reputation: 880

Use break with value

people = {
  :family => [
    {:first => "John", :last => "Doe"},
    {:first => "Jane", :last => "Smith"}
  ]
}

people[:family].each {|index| break index[:last] if index[:first] == "John"}

Upvotes: 1

Maxim
Maxim

Reputation: 9961

puts people[:family].find({}) {|index| index[:first] == "John"}[:last]

Upvotes: 0

Daniel Bonnell
Daniel Bonnell

Reputation: 4997

You can't use return within an each loop. You could use map or collect to return an array of last names like so:

people[:family].collect {|index| index[:last] if index[:first] == "John"}
=> ["Doe", nil]

You could also push your matches to an output variables like so:

output = []
people[:family].each {|index| output << index[:last] if index[:first] == "John"}
=> ["Doe"]

Using break as was suggested, will return a string of the first match, but if you have more than one match, it will not work for you. See example below:

people = {
  :family => [
    {:first => "John", :last => "Doe"},
    {:first => "Jane", :last => "Smith"},
    {:first => "John", :last => "Galt"}
  ]
}
people[:family].each {|index| break index[:last] if index[:first] == "John"}
=> "Doe"

Upvotes: 1

August
August

Reputation: 12558

return needs to be used inside a method:

def foo
  # your code
end

foo # => "Doe"

Upvotes: 0

Related Questions