trouble with if statement in helper function

Is total_time valid too?
It's the only thing that gets converted to string within the if
statement...

Thorsten Mueller wrote:

Is total_time valid too?
It's the only thing that gets converted to string within the if
statement...

yea, if i comment out the if and end statement the program works fine,
but it prints total time every time:

      ret += current_id.to_s + '<br>'
      ret += root_id.to_s

      # if current_id == root_id
        ret += 'Total Time: ' + total_time.to_s + ' minute(s)<br>'
      # end

You didn't post all your code or the error message, so I can only
guess...
The if statement looks ok
since the assigned var is name ret, I guess that's what your helper
returns

Do you have an explicit if statement at end of the method?
Or does more code come?

Otherwise:
If the if statement fails for current_id != root_it,
your method may return nil (result of if)
and the following code may interpret that and fail using it as string

Thorsten Mueller wrote:

You didn't post all your code or the error message, so I can only
guess...
The if statement looks ok
since the assigned var is name ret, I guess that's what your helper
returns

Do you have an explicit if statement at end of the method?
Or does more code come?

Otherwise:
If the if statement fails for current_id != root_it,
your method may return nil (result of if)
and the following code may interpret that and fail using it as string

yea i wonder if it it is trying to put the result from the if statement
as part of the return value.

i'll post the rest of the helper function but i'll warn you it's not
pretty...it does work though...suprisingly.

here is a link to the page so you can see what it does without the if
statement if you are interested:
http://wl-dev.kuliksco.com/manufactures/247

<%= tree_ul(@manufacture, 1, 1, @manufacture.make_time,
@manufacture.id.to_i, @manufacture.id.to_i) %>

and in my helper here is the code:

  def tree_ul(manufacture, total_num, make_num, total_time, root_id,
current_id)

    if manufacture.manufacture_materials.length > 0
      ret = '<ul>'

      manufacture.manufacture_materials.each do |manufacture_material|

      # Get manufacture for material
      manufacture =
Manufacture.find_by_item_id(manufacture_material.item_id)

      if manufacture.blank?
        # Material does not have manufacture

        total_num = total_num * manufacture_material.required_num.to_f /
make_num

        ret += '<table class="collapse"><tr
class="odd_border")><td><li></td>'
        ret += '<td>' + show_image(manufacture_material.image_name) +
'</td>'
        ret += '<td>' + link_to(manufacture_material.name,
manufacture_material) + ' x ' + total_num.ceil.to_s + '&nbsp</td>'
        ret += '</li></tr></table>'
      else
        # Material has manufacture
        #ret += 'make_num=' + manufacture.make_num.to_s + '<br>'
        #ret += 'req_num=' + manufacture_material.required_num.to_s +
'<br>'

        # Calculated total number of materials needed based how many
needed
        make_num = manufacture.make_num.to_f
        total_num = total_num.to_f *
manufacture_material.required_num.to_f / make_num.to_f
        time = manufacture.make_time.to_i * total_num.to_i
        total_time = total_time + time

        ret += '<table class="collapse"><tr
class="even_border"><td><li></td>'
        ret += '<td>' + show_image(manufacture.image_name) + '</td>'
        ret += '<td>' + link_to(manufacture.name, manufacture) + ' x ' +
total_num.ceil.to_s + '&nbsp</td>'
        ret += '<td>(' + time.to_s + ' minute(s) with </td><td>' +
show_image(manufacture.tool.image_name) + '</td>'
        ret += '<td>' + link_to(manufacture.tool.name, manufacture.tool)
+ ')&nbsp</td>'
        ret += '</table>'

        ret += tree_ul(manufacture, total_num, make_num, total_time,
root_id, manufacture.id) if manufacture.manufacture_materials.length > 0

        # Finished looping through all materials for this manufacture,
resetting required number to 1
        total_num = 1

        ret += '</li>'
      end

      end # End loop for materials in manufacture

      ret += '</ul>'

      ret += current_id.to_s + '<br>'
      ret += root_id.to_s + '<br>'

      if current_id == root_id
        ret += 'Total Time: ' + total_time.to_s + ' minute(s)<br>'
      end
    end
  end

line 55 is: ret += tree_ul(manufacture, total_num, make_num,
total_time, root_id, manufacture.id) if
manufacture.manufacture_materials.length > 0

line 18 is: manufacture.manufacture_materials.each do

manufacture_material|

and the error message is:

TypeError in Manufactures#show

Showing manufactures/show.html.erb where line #10 raised:

can't convert nil into String

Extracted source (around line #10):

7: <td><%= link_to @manufacture.tool.name, @manufacture.tool
%>)</td></tr>
8: </table>
9:
10: <%= tree_ul(@manufacture, 1, 1, @manufacture.make_time,
@manufacture.id.to_i, @manufacture.id.to_i) %>
11:
12: <br />
13:

RAILS_ROOT: /u1/app/wonderland-dev
Application Trace | Framework Trace | Full Trace

app/helpers/manufactures_helper.rb:55:in `+'
app/helpers/manufactures_helper.rb:55:in `tree_ul'
app/helpers/manufactures_helper.rb:18:in `tree_ul'
app/helpers/manufactures_helper.rb:55:in `tree_ul'
app/helpers/manufactures_helper.rb:18:in `tree_ul'
app/helpers/manufactures_helper.rb:55:in `tree_ul'
app/helpers/manufactures_helper.rb:18:in `tree_ul'
app/views/manufactures/show.html.erb:10:in
`_run_erb_47app47views47manufactures47show46html46erb'
app/controllers/manufactures_controller.rb:16:in `show'

/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/association_proxy.rb:125:in
`each'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/association_proxy.rb:125:in
`send'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/association_proxy.rb:125:in
`method_missing'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/association_collection.rb:162:in
`method_missing_without_paginate'
vendor/plugins/will_paginate/lib/will_paginate/finder.rb:164:in
`method_missing'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/association_proxy.rb:125:in
`each'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/association_proxy.rb:125:in
`send'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/association_proxy.rb:125:in
`method_missing'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/association_collection.rb:162:in
`method_missing_without_paginate'
vendor/plugins/will_paginate/lib/will_paginate/finder.rb:164:in
`method_missing'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/association_proxy.rb:125:in
`each'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/association_proxy.rb:125:in
`send'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/association_proxy.rb:125:in
`method_missing'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/association_collection.rb:162:in
`method_missing_without_paginate'
vendor/plugins/will_paginate/lib/will_paginate/finder.rb:164:in
`method_missing'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_view/base.rb:637:in
`send'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_view/base.rb:637:in
`compile_and_render_template'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_view/base.rb:365:in
`render_template'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_view/base.rb:316:in
`render_file'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:1100:in
`render_for_file'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:858:in
`render_with_no_layout'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:872:in
`render_with_no_layout'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/layout.rb:262:in
`render_without_benchmark'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/benchmarking.rb:51:in
`render'
/usr/local/lib/ruby/1.8/benchmark.rb:293:in `measure'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/benchmarking.rb:51:in
`render'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/mime_responds.rb:131:in
`send'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/mime_responds.rb:131:in
`custom'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/mime_responds.rb:156:in
`call'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/mime_responds.rb:156:in
`respond'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/mime_responds.rb:150:in
`each'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/mime_responds.rb:150:in
`respond'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/mime_responds.rb:107:in
`respond_to'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:1158:in
`send'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:1158:in
`perform_action_without_filters'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/filters.rb:697:in
`call_filters'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/filters.rb:689:in
`perform_action_without_benchmark'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/benchmarking.rb:68:in
`perform_action_without_rescue'
/usr/local/lib/ruby/1.8/benchmark.rb:293:in `measure'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/benchmarking.rb:68:in
`perform_action_without_rescue'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/rescue.rb:199:in
`perform_action_without_caching'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/caching.rb:678:in
`perform_action'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/abstract/query_cache.rb:33:in
`cache'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/query_cache.rb:8:in
`cache'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/caching.rb:677:in
`perform_action'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:524:in
`send'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:524:in
`process_without_filters'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/filters.rb:685:in
`process_without_session_management_support'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/session_management.rb:123:in
`process'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:388:in
`process'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/dispatcher.rb:171:in
`handle_request'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/dispatcher.rb:115:in
`dispatch'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/dispatcher.rb:126:in
`dispatch_cgi'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/dispatcher.rb:9:in
`dispatch'
/usr/local/lib/ruby/gems/1.8/gems/rails-2.0.2/lib/fcgi_handler.rb:101:in
`process_request'
/usr/local/lib/ruby/gems/1.8/gems/rails-2.0.2/lib/fcgi_handler.rb:149:in
`with_signal_handler'
/usr/local/lib/ruby/gems/1.8/gems/rails-2.0.2/lib/fcgi_handler.rb:99:in
`process_request'
/usr/local/lib/ruby/gems/1.8/gems/rails-2.0.2/lib/fcgi_handler.rb:77:in
`process_each_request'
/usr/local/lib/ruby/gems/1.8/gems/fcgi-0.8.7/lib/fcgi.rb:612:in
`each_cgi'
/usr/local/lib/ruby/gems/1.8/gems/fcgi-0.8.7/lib/fcgi.rb:609:in `each'
/usr/local/lib/ruby/gems/1.8/gems/fcgi-0.8.7/lib/fcgi.rb:609:in
`each_cgi'
/usr/local/lib/ruby/gems/1.8/gems/rails-2.0.2/lib/fcgi_handler.rb:76:in
`process_each_request'
/usr/local/lib/ruby/gems/1.8/gems/rails-2.0.2/lib/fcgi_handler.rb:50:in
`process!'
/usr/local/lib/ruby/gems/1.8/gems/rails-2.0.2/lib/fcgi_handler.rb:24:in
`process!'
public/dispatch.fcgi:27

app/helpers/manufactures_helper.rb:55:in `+'
app/helpers/manufactures_helper.rb:55:in `tree_ul'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/association_proxy.rb:125:in
`each'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/association_proxy.rb:125:in
`send'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/association_proxy.rb:125:in
`method_missing'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/association_collection.rb:162:in
`method_missing_without_paginate'
vendor/plugins/will_paginate/lib/will_paginate/finder.rb:164:in
`method_missing'
app/helpers/manufactures_helper.rb:18:in `tree_ul'
app/helpers/manufactures_helper.rb:55:in `tree_ul'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/association_proxy.rb:125:in
`each'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/association_proxy.rb:125:in
`send'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/association_proxy.rb:125:in
`method_missing'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/association_collection.rb:162:in
`method_missing_without_paginate'
vendor/plugins/will_paginate/lib/will_paginate/finder.rb:164:in
`method_missing'
app/helpers/manufactures_helper.rb:18:in `tree_ul'
app/helpers/manufactures_helper.rb:55:in `tree_ul'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/association_proxy.rb:125:in
`each'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/association_proxy.rb:125:in
`send'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/association_proxy.rb:125:in
`method_missing'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/association_collection.rb:162:in
`method_missing_without_paginate'
vendor/plugins/will_paginate/lib/will_paginate/finder.rb:164:in
`method_missing'
app/helpers/manufactures_helper.rb:18:in `tree_ul'
app/views/manufactures/show.html.erb:10:in
`_run_erb_47app47views47manufactures47show46html46erb'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_view/base.rb:637:in
`send'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_view/base.rb:637:in
`compile_and_render_template'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_view/base.rb:365:in
`render_template'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_view/base.rb:316:in
`render_file'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:1100:in
`render_for_file'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:858:in
`render_with_no_layout'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:872:in
`render_with_no_layout'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/layout.rb:262:in
`render_without_benchmark'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/benchmarking.rb:51:in
`render'
/usr/local/lib/ruby/1.8/benchmark.rb:293:in `measure'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/benchmarking.rb:51:in
`render'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/mime_responds.rb:131:in
`send'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/mime_responds.rb:131:in
`custom'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/mime_responds.rb:156:in
`call'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/mime_responds.rb:156:in
`respond'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/mime_responds.rb:150:in
`each'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/mime_responds.rb:150:in
`respond'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/mime_responds.rb:107:in
`respond_to'
app/controllers/manufactures_controller.rb:16:in `show'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:1158:in
`send'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:1158:in
`perform_action_without_filters'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/filters.rb:697:in
`call_filters'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/filters.rb:689:in
`perform_action_without_benchmark'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/benchmarking.rb:68:in
`perform_action_without_rescue'
/usr/local/lib/ruby/1.8/benchmark.rb:293:in `measure'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/benchmarking.rb:68:in
`perform_action_without_rescue'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/rescue.rb:199:in
`perform_action_without_caching'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/caching.rb:678:in
`perform_action'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/abstract/query_cache.rb:33:in
`cache'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/query_cache.rb:8:in
`cache'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/caching.rb:677:in
`perform_action'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:524:in
`send'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:524:in
`process_without_filters'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/filters.rb:685:in
`process_without_session_management_support'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/session_management.rb:123:in
`process'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:388:in
`process'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/dispatcher.rb:171:in
`handle_request'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/dispatcher.rb:115:in
`dispatch'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/dispatcher.rb:126:in
`dispatch_cgi'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/dispatcher.rb:9:in
`dispatch'
/usr/local/lib/ruby/gems/1.8/gems/rails-2.0.2/lib/fcgi_handler.rb:101:in
`process_request'
/usr/local/lib/ruby/gems/1.8/gems/rails-2.0.2/lib/fcgi_handler.rb:149:in
`with_signal_handler'
/usr/local/lib/ruby/gems/1.8/gems/rails-2.0.2/lib/fcgi_handler.rb:99:in
`process_request'
/usr/local/lib/ruby/gems/1.8/gems/rails-2.0.2/lib/fcgi_handler.rb:77:in
`process_each_request'
/usr/local/lib/ruby/gems/1.8/gems/fcgi-0.8.7/lib/fcgi.rb:612:in
`each_cgi'
/usr/local/lib/ruby/gems/1.8/gems/fcgi-0.8.7/lib/fcgi.rb:609:in `each'
/usr/local/lib/ruby/gems/1.8/gems/fcgi-0.8.7/lib/fcgi.rb:609:in
`each_cgi'
/usr/local/lib/ruby/gems/1.8/gems/rails-2.0.2/lib/fcgi_handler.rb:76:in
`process_each_request'
/usr/local/lib/ruby/gems/1.8/gems/rails-2.0.2/lib/fcgi_handler.rb:50:in
`process!'
/usr/local/lib/ruby/gems/1.8/gems/rails-2.0.2/lib/fcgi_handler.rb:24:in
`process!'
public/dispatch.fcgi:27

Request

Parameters:

{"id"=>"247"}

Show session dump

yes, that's obvious.
The last lines are the if statement. (As long as it fails). This will
return nil and then the recursive call in line 55 fails. (Otherwise it
returns ret and is ok)

Since it's not sure, that ret contains anything at all, something like
that should work:

ret ||= ""

as last line. If ret contains something, that'll be returned, if not
it'll return an empty string.
This would make sure, that the method returns a string in any case.

Thorsten Mueller wrote:

yes, that's obvious.
The last lines are the if statement. (As long as it fails). This will
return nil and then the recursive call in line 55 fails. (Otherwise it
returns ret and is ok)

Since it's not sure, that ret contains anything at all, something like
that should work:

ret ||= ""

as last line. If ret contains something, that'll be returned, if not
it'll return an empty string.
This would make sure, that the method returns a string in any case.

thank you so much!! you just made my day!! it's working now.