5

I expect a while loop to return the last statement it executes, but a function does not seem to return that.

(1) This seems to work..

[10] pry(main)> counter = 0
=> 0
[11] pry(main)> a = counter+=1 while counter < 10
=> nil
[12] pry(main)> a
=> 10

(2) This does not work as I expected. I expect 10 to be returned and stored into b.

[19] pry(main)> def increment(terminal_value)
[19] pry(main)*   counter = 0  
[19] pry(main)*   while counter < terminal_value
[19] pry(main)*     counter+=1
[19] pry(main)*   end  
[19] pry(main)* end  
=> :increment
[20] pry(main)> b = increment(10)
=> nil
[21] pry(main)> b
=> nil

Questions:

  • Why, in (1), does nil get returned from the assignment statement?
  • Why does b not get assigned 10?

Update:

As @DaveNewton mentioned, in (1), I thought I was doing:

a = (counter +=1 while counter < 10)

but I was actually doing:

(a = counter +=1) while counter < 10
kubasub
  • 455
  • 1
  • 5
  • 12
  • 1
    You're doing different things. *(1)* gets a `nil` and displays it, so does *(2)*. In *(1)* you're incrementing a local variable, `counter`, and displaying it. In *(2)* you set a local variable `b` to the return result of calling `increment`, which is `nil`. – Dave Newton Oct 10 '14 at 14:24

2 Answers2

5

In both your examples, the while loop results as nil.

From while loop:

The result of a while loop is nil unless break is used to supply a value.

The same for until:

Like a while loop the result of an until loop is nil unless break is used.

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
0

Supplementing Yu Hao's answer is the answer to this question which states

Any statement in ruby returns the value of the last evaluated expression.

and following that logic if you change your code to (not saying this is good practice or condoning it, just an example):

def increment(terminal_value)
  counter = 0  
    while counter < terminal_value
      counter+=1
    end
  counter
end

b = increment(10)

It will output 10.

Community
  • 1
  • 1
BradyK
  • 387
  • 1
  • 9