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.
精彩评论