ChatGPT解决这个技术问题 Extra ChatGPT

How can I return something early from a block?

If I wanted to do something like this:

collection.each do |i|
   return nil if i == 3

   ..many lines of code here..
end

How would I get that effect? I know I could just wrap everything inside the block in a big if statement, but I'd like to avoid the nesting if possible.

Break would not work here, because I do not want to stop iteration of the remaining elements.


s
sepp2k

next inside a block returns from the block. break inside a block returns from the function that yielded to the block. For each this means that break exits the loop and next jumps to the next iteration of the loop (thus the names). You can return values with next value and break value.


break value didn't work for me, while next value worked fine. Thanks a lot.
I'm not sure your definition of next and break are correct. At the very least, they are confusing. break exits the innermost loop, next moves you to the next iteration. source: tutorialspoint.com/ruby/ruby_loops.htm
@WattsInABox next and break are in no way specific to looping constructs, so the article you linked is very misleading (since it heavily implies the opposite). And my descriptions are definitely correct when next and break are used inside blocks (note that while and for are rarely, if ever, used in Ruby so 99% of uses of next and break are within blocks).
I think you mean non-looping blocks. That's what's confusing about it. Also, I disagree with your 99% assertion, but that's a different argument.
I was looking for a specific method on the Array class to do because I'm so used to having nice things like .detect, .map, .reduce. I knew I was missing something obvious when I couldn't find anything like that. Thanks.
J
JD.
#!/usr/bin/ruby

collection = [1, 2, 3, 4, 5 ]

stopped_at = collection.each do |i|
   break i if i == 3

   puts "Processed #{i}"
end

puts "Stopped at and did not process #{stopped_at}"

S
Sniggerfardimungus

In this instance, you can use break to terminate the loop early:

collection.each do |i|
  break if i == 3
  ...many lines
end

...of course, this is assuming that you're not actually looking to return a value, just break out of the block.


This would not just return from the block, it would return from each. So the loop would end, not continue with the next value. Not sure that that's what's intended.
You can use a value with break in Ruby — break 5 will cause each to return 5.
Thanks, but I don't want to stop iteration.