How exit a block?

I found a suggestion that says to use return, but this generates a
syntax error

colors = [‘red’, ‘yellow’, ‘green’, ‘blue’]

colors.each do |color|
p color
return color if color == ‘yellow’
end

My actual code is a little different but I am assuming whatever
technique solves the above would solve what I need as well.

Seems like a simple syntax need, but I’m not finding a conclusive
solution. Probably right in front of me, so sorry if it’s major
obvious…

– gw

On Thursday 14 August 2008, Greg W. wrote:

My actual code is a little different but I am assuming whatever
technique solves the above would solve what I need as well.

Seems like a simple syntax need, but I’m not finding a conclusive
solution. Probably right in front of me, so sorry if it’s major
obvious…

– gw

break color if color == ‘yellow’

Stefano

Greg W. wrote:

I found a suggestion that says to use return, but this generates a
syntax error

Using ‘return’ will break you out of a method. If you want to use it to
break out of a loop, wrap your loop in a method. i.e.:

#!/usr/bin/ruby

@colors = %w(red blue yellow green)
def find_yellow
@colors.each do |color|
p color
return color if color == ‘yellow’
end
end

puts “I found #{find_yellow}”

HTH,

Josh

Stefano C. wrote:

On Thursday 14 August 2008, Greg W. wrote:

My actual code is a little different but I am assuming whatever
technique solves the above would solve what I need as well.

Seems like a simple syntax need, but I’m not finding a conclusive
solution. Probably right in front of me, so sorry if it’s major
obvious…

– gw

break color if color == ‘yellow’

Oi. yep, break is what I was looking for. I guess I’ve just never come
across it anywhere (and googling anything ruby with “exit block” turns
up 40 billion exit function discussions).

Thx

– gw

Greg W. wrote:

I found a suggestion that says to use return, but this generates a
syntax error

colors = [‘red’, ‘yellow’, ‘green’, ‘blue’]

colors.each do |color|
p color
return color if color == ‘yellow’
end

My actual code is a little different but I am assuming whatever
technique solves the above would solve what I need as well.

Seems like a simple syntax need, but I’m not finding a conclusive
solution. Probably right in front of me, so sorry if it’s major
obvious…

– gw

Your question is not what you really want to ask about.

You don’t want to exit the block. You want to exit the loop that is
inside the each method. And you break out from loops using break.

Just exiting the block would be useless, because you would still be
inside the loop, and the each would just go on to the next iteration. In
fact, you exit the block each time control gets to the end of the block
normally, but then the block is called again in the next iteration.

Have you tried using detect?

colors = [‘red’, ‘yellow’, ‘green’, ‘blue’]
yellow = colors.detect { |color| color == ‘yellow’ }

Detect runs the block on each element until the first that returns true.

colors = [‘red’, ‘yellow’, ‘green’, ‘blue’]
=> [“red”, “yellow”, “green”, “blue”]

yellow = colors.detect { |color| color == ‘yellow’ }
=> “yellow”

– Josh

Greg W. wrote:

Stefano C. wrote:

On Thursday 14 August 2008, Greg W. wrote:

My actual code is a little different but I am assuming whatever
technique solves the above would solve what I need as well.

Seems like a simple syntax need, but I’m not finding a conclusive
solution. Probably right in front of me, so sorry if it’s major
obvious…

– gw

break color if color == ‘yellow’

Oi. yep, break is what I was looking for. I guess I’ve just never come
across it anywhere (and googling anything ruby with “exit block” turns
up 40 billion exit function discussions).

Thx

– gw

Thomas B. wrote:

Your question is not what you really want to ask about.

You don’t want to exit the block. You want to exit the loop that is
inside the each method. And you break out from loops using break.

Just exiting the block would be useless, because you would still be
inside the loop, and the each would just go on to the next iteration. In
fact, you exit the block each time control gets to the end of the block
normally, but then the block is called again in the next iteration.

Note, in some situations next is exactly what you want:
mixed_collection.sort do |x,y|
next x.class.name <=> y.class.name if x.class != y.class
x <=> y
end

As you say though, other times next would be pointless and you want
break.

Best,
P