recursion and variable scope level

A

Adam Akhtar

Hi i want to reverse a string and at the same time check if there are
any spaces using recursion. I can get the string to reverse fine but
cant detect when theres a space

heres my code

def reverse_string a_string, an_index, spaces
spaces = true if a_string[an_index - 1].chr == ' '
if an_index == 1
return a_string[an_index - 1].chr
else
return a_string[an_index - 1].chr + reverse_string(a_string,
an_index - 1, spaces)
end

end

and i call it like this

spaces = false
str = "hello people"
puts reverse_string str, str.length, spaces
puts "Spaces present? #{spaces}"

spaces in the end is set as false though it should be set to true. Is
this soemthing to do with variable and parameter scope?
 
A

Adam Akhtar

oh and im doing this as a way to practice recursion. Using
string.reverse would of course be the simpler way of doing this.
 
B

Brian Candler

Adam said:
spaces in the end is set as false though it should be set to true. Is
this soemthing to do with variable and parameter scope?

Yes. The 'spaces' inside the method definition is a completely separate
variable to the 'spaces' you use outside, since 'def' starts a fresh
scope.

One solution is to return both str and spaces from your function:

def reverse_string a_string, an_index, spaces
spaces = true if a_string[an_index - 1].chr == ' '
if an_index == 1
return a_string[an_index - 1].chr, spaces
else
r1, r2 = reverse_string(a_string, an_index - 1, spaces)
spaces ||= r2
return a_string[an_index - 1].chr + r1, spaces
end

end

#and i call it like this

str = "hello people"
rev, spaces = reverse_string str, str.length, spaces
puts rev
puts "Spaces present? #{spaces}"

Another option is to pass a lambda, which is a function which is called
whenever a space is detected.

def reverse_string a_string, an_index, spaces
spaces.call if a_string[an_index - 1].chr == ' '
if an_index == 1
return a_string[an_index - 1].chr
else
return a_string[an_index - 1].chr + reverse_string(a_string,
an_index - 1, spaces)
end

end

#and i call it like this

spaces = false
str = "hello people"
puts reverse_string str, str.length, lambda { spaces=true }
puts "Spaces present? #{spaces}"
 
A

Adam Akhtar

I dont believe i only just found out that functions can return more than
one variable in ruby!

How I missed that i dont know.

Thank you very much for your help on that.
 
B

Brian Candler

Adam said:
I dont believe i only just found out that functions can return more than
one variable in ruby!

How I missed that i dont know.

Thank you very much for your help on that.

No problem.

Really they are just returning an array, and that array may (or may not)
be split at the receiver.

irb(main):001:0> def foo; return 1,2; end
=> nil
irb(main):002:0> x = foo
=> [1, 2]
irb(main):003:0> x, y = foo
=> [1, 2]
irb(main):004:0> x
=> 1
irb(main):005:0> y
=> 2
irb(main):006:0> def bar; return [1,2]; end
=> nil
irb(main):007:0> x = bar
=> [1, 2]
irb(main):008:0> x, y = bar
=> [1, 2]
irb(main):009:0> x
=> 1
irb(main):010:0> y
=> 2

I believe there's no difference whether you build an array to return, or
give multiple values to return.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,189
Members
46,735
Latest member
HikmatRamazanov

Latest Threads

Top