Search code examples
rubymethodsfactorial

Global vs local variables?


I am wondering why my code works in one instance but doesn't in another. Does it have something to do with local and global variables?

This works:

def factorial num
  result = 1
  while (num > 1)
    result = result * num
    num -= 1
  end
  puts result
end

This doesn't work:

result = 1

def factorial num
  while (num > 1)
    result = result.to_i * num
    num -= 1
  end
  puts result
end

Solution

  • Everything inside of a method definition cannot see local variables from other places. That sounds weird, but here's two ways to fix it:

        result = 1
        number = 10
    
        def factorial(num,result_value)
          while (num > 1)
            result_value = result_value.to_i * num
            num -= 1
          end
          puts result_value
        end
    
        factorial(number, result)
    

    That passes result as an argument. That's a great way of handling the method because it doesn't allow you to change the value of result from within the method. That might not seem like a big deal but "pure methods" like this become very valuable as the size the code increases.

    This is the "dirty" or un-pure way of doing the same thing:

    @result = 1
    
    def factorial(num)
      while (num > 1)
        @result = @result.to_i * num
        num -= 1
      end
      puts @result
    end
    

    Putting an @ in front of a variable name allows its scope to expand to methods defined outside of its scope. This becomes a problem as the complexity of your code increases.

    Random personal opinion: even though Ruby doesn't require you to put the parentheses next to a method definition, you always should. It makes the code a lot more explicit and easier to read. Follow your heart though ;)