Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confusion with the order of execution when `next` with `unless` in ruby

Tags:

ruby

The next statement is used to skip a part of the loop and continue with the next iteration of the loop. It can be used in combination with for and while statements.

I have seen people using next if there is complicated piece of code after some condition is being evaluated i.e

next if @state!=:some_state
# some long complicated code

Now here I have played with the next in my IRB as below :

n = 1
loop do
  n = n + 1
  next unless n == 10
  print "Good"
  break
end
# Good=> nil

The above one understood. Nicely clear.

n = 1
#=> 1
loop do
  print "#{n}"
  n = n + 1
  next puts "hi" unless n == 5
  p "good"
  break
end
#1hi
#2hi
#3hi
#4"good"
#=> nil

In the above code, couldn't understand about which order the lines puts "hi" and unless n == 5 executed. Which executed first?

The below one leads to the infinite Loop.

n = 1
#=> 1
loop do
  print "#{n}"
  n = n + 1
  next puts "hi"; 2 + 3 unless n == 5
  p "good"
  break
end

whereas this one is good:

n = 1
#=> 1
loop do
  print "#{n}"
  n = n + 1
  next puts "hi", 2 + 3 unless n == 5
  p "good"
  break
end

#1hi
#5
#2hi
#5
#3hi
#5
#4"good"
#=> nil

Please help me here to understand - how does this one resolve that forever loop ?

like image 656
Arup Rakshit Avatar asked Oct 20 '25 01:10

Arup Rakshit


1 Answers

A semicolon is evaled as a line break so:

next puts "hi"; 2 + 3 unless n == 5

would be equivalent to:

next puts "hi"
2 + 3 unless n == 5

Therefore, next will always be called and you'll have an infinite loop.

The comma is evaled as passing a set of arguments (which is interpreted as an array by puts method signature), so:

next puts "hi", 2 + 3 unless n == 5

is equivalent to:

next puts("hi", 2 + 3) unless n == 5

Regarding the execution order of puts and unless - consider the following:

unless n == 5
  next puts "hi"
end

In this example, it is obvious that unless is evaluated first, then if the condition passed is evaluated to false the next puts "hi" statement is executed. Well:

next puts "hi" unless n == 5

is shorthand for exactly the same thing. So the unless modifier will always be evaluated first. Naturally, if you insert a semicolon in the middle, it would cause this to be evaluated differently, since the semicolon is evaluated as a line break.

like image 133
PinnyM Avatar answered Oct 21 '25 19:10

PinnyM