Jamie
Jamie

Reputation: 3931

Why do while modifiers behave differently with blocks?

irb(main):186:0* begin puts "abc" end while false
abc
=> nil
irb(main):187:0> puts "abc" while false
=> nil

So when you use a block with the while modifier, the block is executed once (which seems like a do-while loop in many other languages). But if you use a single statement with the while modifier then it becomes more like just a while loop, where the condition is checked first. This seeks kind of surprising so why does the behavior exist?

Upvotes: 2

Views: 83

Answers (3)

matt
matt

Reputation: 79733

This seems to be just a quirk of the language. ... while condition acts a a statement modifier except when it is after a begin ... end, where it behaves like a do ... while loop from other languages.

Yukihiro Matsumoto (Matz, the creator of Ruby) has said he regrets this, and would like to remove this behaviour in the future if possible.

There’s a bit more info in this blog post from New Relic, where I found the link to the mail list post: https://blog.newrelic.com/2014/11/13/weird-ruby-begin-end/

Upvotes: 1

Pedro Ivan
Pedro Ivan

Reputation: 332

Do while ensures at least one execution, but the second one is not a do while, is one of many sintax sugar of ruby. Its equivalent to

while false
  puts 'abc'
end

Just remember the

puts 'abc' if false

Both are behaviouring correctly.

Upvotes: 1

Anthony
Anthony

Reputation: 15967

I think your confusion lies in the fact that begin/end is not considered a block. To showcase your example with a block take a look at this:

[3] pry(main)> loop { puts "hi" } while false
=> nil

Upvotes: 1

Related Questions