When attempting to return out of a function’s loop, the following return statement instead behaves like a break statement: breaking out of the loop but not returning from the function.
function mweret()
# write temp file
fn = "temp.txt"
write(fn, "1\n2\n3\n2\n1\n")
# read temp file
nLine = 0
linePrev = ""
open(fn, "r") do f
while !eof(f)
line = readline(f, keep=true)
print(line)
nLine += 1
if linePrev > line
println("non-increasing order at line $nLine")
close(f)
rm(fn)
return nothing
end
linePrev = line
end
end # open
println("POST LOOP!")
end
In contrast, when looping through similar elements but in a vector, the return statement behaves as expected: breaking out of the loop AND returning from the function.
function mweret2()
iPrev = 0
nElement = 0
for i in [1; 2; 3; 2; 1]
println("$i")
nElement += 1
if iPrev > i
println("non-increasing order at element $nElement")
return nothing
end
iPrev = i
end
println("POST LOOP!")
end
The open(...) do notation defines a new anonymous function in the indented block, which is then passed to open as a first parameter. Therefore, the return inside the block exits the anonymous function back into mweret.
In the second function mweret2, the return exits mweret2 function as expected.
TL;DR The do notation is a confusing at first (for me too), but then becomes natural and useful.
function mweret()
# write temp file
fn = "temp.txt"
write(fn, "1\n2\n3\n2\n1\n")
# read temp file
nLine = 0
linePrev = ""
open(fn, "r") do f
while !eof(f)
line = readline(f, keep=true)
print(line)
nLine += 1
if linePrev > line
println("non-increasing order at line $nLine")
break
end
linePrev = line
end
end # open
println("POST LOOP!")
end
In my application, I want to break out of the loop AND avoid the post loop processing AND abort the application. So my simple fix was to use the error function.
You could also let the anonymous function return something informative like a Symbol or Bool flag. E.g.
function mweret(seq)
# write temp file
fn = tempname()
write(fn, join("$x\n" for x in seq))
# read temp file
nLine = 0
linePrev = ""
open(fn, "r") do f
while !eof(f)
line = readline(f, keep=true)
print(line)
nLine += 1
if linePrev > line
println("non-increasing order at line $nLine")
return false # Indicates we stopped early
# Cleanup is handled by open(::Function, ...) itself
end
linePrev = line
end
return true # We went through the entire file
end || return # (or exit() instead of return if you want to terminate the application)
println("POST LOOP!")
end
julia> mweret([1, 2, 3, 4, 5])
1
2
3
4
5
POST LOOP!
julia> mweret([1, 2, 3, 2, 1])
1
2
3
2
non-increasing order at line 4