# Recursive function problem

**URL:** <https://www.ruby-forum.com/t/recursive-function-problem/177566>\
**Category:** Ruby\
**Created:** [October 20, 2009, 11:32am UTC](https://www.ruby-forum.com/t/recursive-function-problem/177566 "2009-10-20T11:32:27Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![olistik](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/9de0a6/32.png) [@olistik](https://www.ruby-forum.com/u/olistik)\
**Post date:** [October 20, 2009, 11:32am UTC](https://www.ruby-forum.com/t/recursive-function-problem/177566/1 "2009-10-20T11:32:27Z")

</div>

Hi all!

I have a problem with this function, which should return a formatted  
string of an hash given as an argument:

def show\_params(params, tabs\_num)  
params\_str = String.new if tabs\_num == -1  
tabs\_num++  
params.each do |key, value|  
tabs\_num.times { params\_str += “\t” }  
if params.class != value.class  
params\_str += "#{key} =\> " + value.to\_s + “\n”  
else  
params\_str += “#{key} =\> \n”  
show\_params(value, tabs\_num)  
end  
end  
return params\_str  
end

I call the function with this:  
show\_params(params, -1)

obtaining thish error (in Rails):

undefined method `+@’ for {“action”=\>“edit”, “id”=\>“51”,  
“controller”=\>“items”}:HashWithIndifferentAccess

I cannot guess the reason! Any idea?

Thanks!

---

<div class="post-metadata">

**Author:** ![olistik](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/9de0a6/32.png) [@olistik](https://www.ruby-forum.com/u/olistik)\
**Post date:** [October 20, 2009, 4:30pm UTC](https://www.ruby-forum.com/t/recursive-function-problem/177566/2 "2009-10-20T16:30:19Z")

</div>

> I don’t really know how to read the docs, but this seems like the kind  
> of  
> thing that I would expect the pp library to do for us. I tried about 15  
> different ways to get it to do this, and only ever got the same as the  
> default p function. If pp does address this issue, can someone explain  
> how  
> to get it to work?

Bravo!!!

I come from PHP and my first need was a function similar to print\_r() (I  
develop with Rails 2 now), so I just started (very lazily 🙂 ) to write  
it… and you are giving me the code, written with a ruby philosophy!  
Many thanks!!! Anyway, it’s less bizarre that a such modern language  
doesn’t implement in native libraries these prehistorical functions, I  
think…

---

<div class="post-metadata">

**Author:** ![olistik](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/9de0a6/32.png) [@olistik](https://www.ruby-forum.com/u/olistik)\
**Post date:** [October 20, 2009, 12:26pm UTC](https://www.ruby-forum.com/t/recursive-function-problem/177566/3 "2009-10-20T12:26:23Z")

</div>

On Tue, Oct 20, 2009 at 4:32 AM, Maurizio De santis \<  
removed\_email\_address@domain.invalid\> wrote:

> ```
> if params.class != value.class
> 
> ```
> 
> show\_params(params, -1)  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

In Ruby ++ isn’t defined  
tabs\_num++  
should instead use += like this  
tabs\_num+=1

* * *

Also, you can specify default values for parameters, so  
def show\_params(params, tabs\_num)  
could be rewritten:  
def show\_params(params, tabs\_num = -1)

Which would allow you to take the current call of  
show\_params(params, -1)  
and instead call it like this  
show\_params(params)

This allows you to keep internal knowledge inside, people calling the  
function shouldn’t have to know that they need to initialize some  
internal  
variable to -1

* * *

You still have an issue in that you only initialize the variable  
params\_str  
on the first call to the function, so in the future calls, this variable  
is  
not defined, and you cannot then concatenate additional string to it. To  
resolve this, remove the if on it, so that it is initialized for each  
recursive call. Then you actually get some output. Now, what to do with  
this  
variable? Well, we want to take the results of the recursive calls, and  
add  
them into the current string. Notice right now you are saying

params\_str += “#{key} =\> \n”  
show\_params(value, tabs\_num)

But this second line does nothing, it calculates the substring, then  
returns  
it but nothing receives it or does anything with it. So instead, try

params\_str += “#{key} =\> \n”  
params\_str += show\_params(value, tabs\_num)

* * *

Anyway, here is what I have, and it does what I think you are wanting it  
to  
do:

def show\_params( params , tabs\_num = -1 )  
tabs\_num += 1  
params\_str = String.new  
params.each do |key, value|  
params\_str \<\< “\t” \* tabs\_num  
if value.is\_a? Hash  
params\_str \<\< “#{key.inspect} =\>\n#{show\_params value , tabs\_num}”  
else  
params\_str \<\< “#{key.inspect} =\> #{value.inspect}\n”  
end  
end  
params\_str  
end

params = { :abc =\> ‘def’ , 3 =\> {1=\>true,2=\>{‘xyz’=\>/xyz/}} , 5 =\> 5 }  
puts show\_params(params)

* * *

I don’t really know how to read the docs, but this seems like the kind  
of  
thing that I would expect the pp library to do for us. I tried about 15  
different ways to get it to do this, and only ever got the same as the  
default p function. If pp does address this issue, can someone explain  
how  
to get it to work?

---

<div class="post-metadata">

**Author:** ![olistik](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/9de0a6/32.png) [@olistik](https://www.ruby-forum.com/u/olistik)\
**Post date:** [October 20, 2009, 5:02pm UTC](https://www.ruby-forum.com/t/recursive-function-problem/177566/4 "2009-10-20T17:02:09Z")

</div>

On Tue, Oct 20, 2009 at 9:30 AM, Aurora S.r.l.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)wrote:

> ## I come from PHP and my first need was a function similar to print\_r() (I develop with Rails 2 now), so I just started (very lazily 🙂 ) to write it… and you are giving me the code, written with a ruby philosophy! Many thanks!!! Anyway, it’s less bizarre that a such modern language doesn’t implement in native libraries these prehistorical functions, I think…
> 
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

Well, if you just need to look at it, inspect usually works. It’s just  
when  
you get long lists or lots of nesting, using inspect sometimes still  
isn’t  
enough. I really think that pp should do it, but can’t figure out how.

If I were doing it, myself, I would monkey patch it into the hash class,  
something like this:

class Hash  
def readable( tabs\_num = -1 )  
tabs\_num += 1  
self.inject(String.new)do | str , ( key , value ) |  
rhs = value.is\_a?(Hash) ? “\n#{value.readable tabs\_num}” :  
“#{value.inspect}\n”  
str \<\< “#{”\t" \* tabs\_num}#{key.inspect} =\> #{rhs}"  
end  
end  
end

params = { :abc =\> ‘def’ , 3 =\> {1=\>true,2=\>{‘xyz’=\>/xyz/}} , 5 =\> 5 }  
puts params.readable

But some people here hate monkey patching, so I didn’t post that  
earlier.

Also, I found that YAML gives something very similar to what we are  
doing  
here, with

require ‘yaml’  
puts params.to\_yaml
