Andy B
Andy B

Reputation: 49

Strange result in Ruby with "end if"

I expect this code to execute the code block and result in the output "x" and "y", or just to throw a syntax error:

if true
  puts "x"
end if
puts "y"

However, the interpreter ignores the if true block and only executes puts "y". If I instead enter the following code:

if true
  puts "x"
end if

the interpreter exits with an end-of-input syntax error. Is there a reason why the first snippet is valid code but somehow executing wrong? It would seem to me that there is some error in the parser.

I've confirmed this in Ruby 2.1.2 as well as Ruby 2.1.5.

Upvotes: 3

Views: 1524

Answers (4)

Mark
Mark

Reputation: 684

Your code is effectively saying only to execute the if true block only if puts "y" returns true. Unfortunately, puts returns nil. To end an if statement in Ruby, you simple have to use end. Unlike in Shell Scripting or Visual Basic, there is no specific end statements for different blocks.

Change

if true
  puts "x"
end if
puts "y"

to

if true
  puts "x"
end
puts "y"

And you'll be golden.

Upvotes: 0

tekina
tekina

Reputation: 572

Your code is incorrect. The correct code is:

if true
  puts "x"
end
puts "y"

Your code tells Ruby to execute the if true ... end block if puts "y" returns true. puts returns nil, which amounts to false in a condition check, leading to the block not being executed at all.

Upvotes: 1

spickermann
spickermann

Reputation: 106782

There are two things playing together here:

  1. The return value of the puts is nil
  2. Ruby is usually clever enough to read the next line if the current command hasn't ended yet.

That means:

if true
  puts "x"
end if
puts "y"

is the same than:

if true
  puts "x"
end if (puts "y")

Ruby evaluates puts "y" to nil:

if true
  puts "x"
end if nil

What leads Ruby to not evaluate the if true block, because if nil acts like if false.


Or in other words: Your example is the same as:

if puts("y") # evaluates to nil (aka is falsey)
  if true
    puts "x"
  end 
end

Upvotes: 6

Michael Laszlo
Michael Laszlo

Reputation: 12239

I think what you mean to write is

if true
  puts "x"
end 
puts "y"

That would produce the output you expect.

Upvotes: 3

Related Questions