From: Josh Cheek Date: 2009-10-20T19:25:56+09:00 Subject: Re: recursive function problem --000e0cd2114e8f0d1004765b49c3 Content-Type: text/plain; charset=ISO-8859-1 On Tue, Oct 20, 2009 at 4:32 AM, Maurizio De santis < desantis.maurizio@gmail.com> wrote: > 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! > -- > Posted via 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? --000e0cd2114e8f0d1004765b49c3--