开发者

Ruby: `gsub': can't convert nil into String (TypeError)

def export_no_sdesc(item_no = " ", make = " ", model = " ", list_price = " ", long_desc = " ", global_image_path = " ")
final_image_path = global_image_path + item_no + ".jpg"
final_thumbs_path = global_image_path + "thumbs/" + item_no + ".jpg"
Dir.glob("body.tmp") do |filename|
    body = file_as_string(filename)
    body = body.gsub("item_no", item_no).gsub("image_path", final_image_path).gsub("image_thumb", final_thumbs_path)
    body = body.gsub("part_make", make).gsub("part_model", model).gsub("long_desc", long_desc).gsub("list_price", list_price)
    File.open('page_export.html', 'a') do |x|
        x.puts body
        x.close
    end
  end
end

The above function is giving me fits. First, it reads in some strings from a text file. Then, it reads in a text file that's a template for part of a HTML table. Next, it replaces certain keywords in the template file with the contents of the strings, and lastly, it pushes it all to a new text file (page_export.html).

The problem here is that some fields that are being imported in the text file are blank, or at least, I think that's the problem. Either way, I get this error:

john@starfire:~/code/ruby/idealm_db_parser$ ruby html_export.rb
html_export.rb:34:in `gsub': can't convert nil into String (TypeError)
from html_export.rb:34:in `export_no_sdesc'
from html开发者_StackOverflow_export.rb:31:in `glob'
from html_export.rb:31:in `export_no_sdesc'
from html_export.rb:82
from html_export.rb:63:in `each'
from html_export.rb:63
from html_export.rb:56:in `glob'
from html_export.rb:56

To remedy this, not only did I declare a whitespace as a default argument for each string, but in another part of the script, I loop through each string - and if it's empty, I append a whitespace. Still no luck.

I have a function that's almost identical to the one above, but it operates over a slightly different set of data - one that doesn't have any empty strings - and it works great. I've also tested the code that appends the whitespace, and it works fine, too.

So, what am I doing wrong?


Quite simply, one of your function arguments is nil. It doesn't matter if you'ved supplied default empty strings if you're passing a nil in.

We can't possibly tell which argument is nil from the code provided, so check them all, and, assuming an error is thrown, start checking them individually. Add the following to the top of your function:

[item_no, make, model, list_price, long_desc, global_image_path].each do|i|
  throw "nil argument" if i.nil?
end

Update

Default arguments don't prevent you from passing in nil. They only come into effect if you don't supply anything.

Here:

def test(x = 3)
  puts x
end

test()    # writes '3'
test(nil) # writes 'nil'


Change

    body = file_as_string(filename)

into

    throw body = file_as_string(filename)

If it gives you nil, then you have some problems with body.tmp file.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜