Uses of interrupts and returns in Ruby programming

Time:2019-10-3

The use of return, break and next involves the problem of jumping out of scope, and their difference lies in the different purpose scope of jumping out of different keywords, because there are some places that need special attention because of code blocks.
return
Common ways

Usually the return statement means the same thing as everyone understands.

def m1 param
 if param == 1
  return 'returned 1'
 end
 'returned default value' According to the Ruby language specification, the result of the last execution statement will be returned as a return value, and return is optional.
end

m1(1) # => returned 1
m1(2) # => returned default value

In the case of ensure with exception capture, the situation is slightly different:


def m1
 'return default'
ensure
 puts 'I am sure that it will be here!'
end

m1 # => return default

In this case, the M1 method returns the value before the ensure statement, whether or not the return is displayed. The ensure statement simply ensures that the subsequent block of code put’I am sure that it will be here!’is executed, but it will not be returned from here. If the return value is displayed in the ensure statement, the situation is different. Examples are as follows:


def m1
 return 'return default'
ensure
 return 'I am sure that it will be here!'
end

m1 # => I am sure that it will be here!

Whether the return is displayed before ensure or not, only the value after ensure is returned.

In the case of code block intervention, it will be different:

def m1
 p 'start ... '
 proc do
  p 'block start'
  return
  p 'block end'
 end.call
 p 'end ... '
end

m1

# Output results:
#
# "start ... "
# "block start"

This should be expected. Look at the next one:

def m1
 p 'start ... '
 -> do
  p 'block start'
  return
  p 'block end'
 end.call
 p 'end ... '
end

m1

# Output results:
#
# "start ... "
# "block start"
# "end ... "

There’s an extra line “end…” here. What’s the reason? This is the biggest difference between Proc and Lambda, in which return statements jump out of the purpose scope is different, Proc will jump out of the whole method call directly, and Lambda will only jump out of its scope and return to the method to continue execution, which requires special attention. (In break, Proc and Lambda jump out in the same way as return, which will not be repeated later.)
break

Let’s start with a simple example:


result = [1, 2, 3, 4, 5].map do |i|
 i * 2
end

p result # => [2, 4, 6, 8, 10]

This is nothing strange. Let’s take a look at the following, and guess what its output is.


result = [1, 2, 3, 4, 5].map do |i|
 break if i > 3
 i * 2
end
# FLAG
p result

Is it [1, 2, 3, nil, nil]? Or [1, 2, 3]? Or what? The answer is nil, because after breaking, it jumps directly to FLAG, that is to say, it jumps out of map method, and the statement in map method has not been executed, resulting in no return value. In order to verify this idea, we can use Ruby language break to bring back the characteristics of the return value to verify:


result = [1, 2, 3, 4, 5].map do |i|
 break 'returned break' if i > 3
 i * 2
end

p result # => "returned break"

Here we can prove that our guess is correct. Although this problem is explained above, it should not be very easy to understand. We define a code block ourselves. Let’s explain again:

def m1
 p 'start in m1 ... '
 M2 do # code block
  p 'start in block in m1 ... '
  p 'end in block in m1 ... '
 end
 p 'end in m1 ... '
end

def m2 &block
 p 'start in m2 ... '
 block.call
 p 'end in m2 ... '
end

m1

# Output results:
#
# "start in m1 ... "
# "start in m2 ... "
# "start in block in m1 ... "
# "end in block in m1 ... "
# "end in m2 ... "
# "end in m1 ... "

Then we add break to the block in M1 to see the execution result:

def m1
 p 'start in m1 ... '
 M2 do # code block
  p 'start in block in m1 ... '
  break
  p 'end in block in m1 ... '
 end
 p 'end in m1 ... '
end

def m2 &block
 p 'start in m2 ... '
 block.call
 p 'end in m2 ... '
end

m1

# Output results:
#
# "start in m1 ... "
# "start in m2 ... "
# "start in block in m1 ... "
# "end in m1 ... "

You can see that the last line of code block is not executed, and the last line of M2 is not executed, because this line is not executed, resulting in the map in the second example of break not returning any value. To sum up, breaks in code blocks jump directly out of the called method (m2), while the remaining statements in the method (m1) that declares the code block continue to be executed.
next

The next keyword is similar to continue in other languages, and it works in a similar way to continue.

def m1
 p 'start in m1 ... '
 M2 do # code block
  p 'start in block in m1 ... '
  next
  p 'end in block in m1 ... '
 end
 p 'end in m1 ... '
end

def m2 &block
 p 'start in m2 ... '
 block.call
 p 'end in m2 ... '
end

m1

# Output results:
#
# "start in m1 ... "
# "start in m2 ... "
# "start in block in m1 ... "
# "end in m2 ... "
# "end in m1 ... "

Just skipping the last line of code block, that’s how Next works. Let’s take a look at the example of break. If we use next to write, let’s see what the result is. If you fully understand what has been written above, you will be able to calculate the results in your brain.


result = [1, 2, 3, 4, 5].map do |i|
 next if i > 3
 i * 2
end

p result # => [2, 4, 6, nil, nil]

Next statements can also bring back values:


result = [1, 2, 3, 4, 5].map do |i|
 next 'next' if i > 3
 i * 2
end

p result # => [2, 4, 6, "next", "next"]

Other

For return, it can be used in code blocks in methods, while break and next can only be used in code blocks (they can also be used in loop structures, but generally they are also expressed in code blocks). If they are called in methods, they will prompt syntax errors, that is:


def m1
 return # OK
 break # Invalid break, compile error (SyntaxError)
 next  # Invalid next, compile error (SyntaxError)
end

conclusion

Return is mostly the same as other languages, and you need to pay attention to the details in ensure and Proc and Lambda code blocks.

Break in a block of code in a method nested call should be noted that it always returns to the method in which the block method is invoked (a bit around).

Next is the most honest, basically need not pay attention to anything.

Finally, not only return returns values, but also breaks and next returns values.

Recommended Today

Details of multi-path and large capacity hard disk mount under CentOS

I. application environment and requirementsBlade servers connect HP storage through fiber switches, forming a 2×2 link The storage capacity of the operating system for CentOS 6.4 64 bit mount is 2.5t Based on this application environment, two problems need to be solved: In order to ensure the stability and transmission performance of the link, multi-path […]