Trt Trt
Trt Trt

Reputation: 5532

Ruby recursion error

Does anyone know why this code:

sum=0
def get_sum n
    return sum if n<1
    sum=sum+n
    get_sum(n-1)
end 

get_sum 10

gives me this?

rb:3:in `get_sum': undefined local variable or method `sum' for main:Object (NameError)
from 1.rb:8:in `<main>'

The code makes perfectly sense, and you can understand what it is doing.

Upvotes: 0

Views: 194

Answers (5)

scones
scones

Reputation: 3345

You never initialized the variable sum before using it.

You can totally avoid using that variable, since it does nothing:

def get_sum n
    return 0 if n<1
    get_sum(n-1) + n
end 

get_sum 10

Upvotes: 0

brymck
brymck

Reputation: 7663

Rather than using a global variable, another method using recursion would be like this (limited by stack depth, I guess):

def get_sum(n)
  return n if n < 1
  n + get_sum(n - 1)
end

sum = get_sum(10)

If you ever use a Ruby implementation that offers tail call optimization (I don't know of any implementations that do), ProGNOMmers's method would be a bit nicer on the stack, but as is a quick test has both exceeding the maximum stack level around n = 9000 or so. Not that you should be recursing 9000 times or anything.

Upvotes: 2

mdesantis
mdesantis

Reputation: 8517

As @Dogbert wrote, normal variables declared outside a function are not accessible inside the function.

This is an approach which doesn't use global variables (which are not suited for recursion):

def get_sum(n, sum = 0)
    return sum if n<1
    get_sum(n-1, sum+n)
end 

get_sum(10) #=> 55

Upvotes: 1

aherve
aherve

Reputation: 4070

You might want to try this :

def get_sum n
    return n if n == 0
    return n + get_sum(n-1)
end 

In this version you don't need to instanciate any global variable ( which is not a good idea ), and you actually perform a regressive sum :)

Upvotes: -1

Dogbert
Dogbert

Reputation: 222118

Normal variables declared outside a function are not accessible inside the function.

You could prefix sum with $ to make it a global variable (not usually a good idea.)

$sum=0
def get_sum n
    return $sum if n<1
    $sum=$sum+n
    get_sum(n-1)
end 

get_sum 10
#= 55

If you have a real test case where you want to do this, I can suggest a suitable approach if you want.

Upvotes: 3

Related Questions