The use of the return, break, next keywords all involve the problem of jumping out of scope, and their difference lies in the different scope of the purpose of jumping out of different keywords, because there are code blocks that cause some places to be Pay special attention.
return
Common way
The return statement under normal circumstances is the same 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 executed statement will be returned as the return value
, Retu rn is optional
end
m1 (1) # => returned 1
m1 (2) # => returned default value
When there is an exception to capture the situation, the situation will be slightly different:
def m1
'return default'
ensure
puts 'I am sure that it will be here!'
end
m1 # => return default
In this case, before the ensure statement, regardless of whether it is displayed with return or not, the m1 method will return the value before ensure. The ensure statement just ensures that the code block after puts 'I am sure that it will be here!' Will not return from here. If you use return to return the value shown 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!
No matter whether return is displayed before ensure, only the value after ensure will be returned.
With the intervention of the code block, it will be different:
def m1
p 'start ...'
proc do
p 'block start'
return
p 'block end'
end.call
p 'end ...'
end
m1
# Output result:
##
# "start ..."
# "block start"
This should be expected, then look at the next one:
def m1
p 'start ...'
-> do
p 'block start'
return
p 'block end'
end.call
p 'end ...'
end
m1
# Output result:
##
# "start ..."
# "block start"
# "end ..."
There is an extra line "end ...", why? This is the biggest difference between Proc and Lambda. The return scope of the return statement among them is different. Proc will directly jump out of the entire method call, and Lambda will only jump out of its own scope and return to the method to continue execution. This point requires special attention. (In break, Proc and Lambda jump out the same way as return, so I wo n’t go into details later.)
break
Let's first look at a simple example:
result = [1, 2, 3, 4, 5] .map do | i |
i * 2
end
p result # => [2, 4, 6, 8, 10]
There is nothing strange about this, so look at the following to 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]? then what? The answer is nil, because after the break is executed, it jumps directly to FLAG, which is to jump out of the map method, and the statement in the map method has not been executed, resulting in no return value. In order to verify that this idea is correct, we can use Ruby Language break can be verified with the return value feature:
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 the problem is explained above, it should not be very easy to understand. Let's define a code block and explain it 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 result:
##
# "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 result:
##
# "start in m1 ..."
# "start in m2 ..."
# "start in block in m1 ..."
# "end in m1 ..."
It can be seen that the last line of code in the code block is not executed, and the last line of m2 is not executed, because this line is not executed, which causes the map in the second example of break to return no value. To sum up, the break in the code block will directly jump out of the called method (m2), and continue to execute the remaining statements in this method (m1) in the method (m1) that declares the code block.
next
The next keyword is similar to continue in other languages, and it works basically similar 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 result:
##
# "start in m1 ..."
# "start in m2 ..."
# "start in block in m1 ..."
# "end in m2 ..."
# "end in m1 ..."
Just skipping the last line of code in the code block, this is how next works. Let's take a look at the break example again. If we write it with next, what is the result? If you fully understand what is written above, I believe you can already calculate the result 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]
The next statement can also bring a return value:
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, in the method, it can be used in the code block, and break and next can only be used in the code block (can also be used in the loop structure, but generally it is also expressed in the form of code block), if in the method Calling both will prompt a syntax error, that is:
def m1
return # OK
break # Invalid break, compile error (SyntaxError)
next # Invalid next, compile error (SyntaxError)
end
in conclusion
In most cases, return is no different from other languages. You need to pay attention to the details in ensure and Proc and Lambda.
break needs to be noted in the code block in the method nested call, it always returns to the method of calling the code block method (a bit around).
next The most honest, basically need not pay attention to anything.
Finally, not only return can return values, but both break and next can return values.
Original address: http://my.oschina.net/oneapmofficial/blog/468578