Can't convert nil to string - edit to recount all failed attempts
At the point of my code, I expect current_part
it will sometimes be nil
, and I want to run some code (inside a block if
) if it doesn't.
Using script/server --debugger
, I have established that it current_part
is actually nil
the moment the following errors occur.
All of the following versions generate an error can't convert nil into String
on the second line:
#
def map_concepts_to_part(part, current_part)
if current_part
part.concepts.map { |concept| content_tag(:li, "stuff...")}.join
end
end
#
def map_concepts_to_part(part, current_part)
if test_if_exists(current_part)
part.concepts.map { |concept| content_tag(:li, "stuff...")}.join
end
end
def test_if_exists(test_subject)
test_subject rescue nil
end
#
def map_concepts_to_part(part, current_part)
if test_if_complete(current_part)
part.concepts.map { |concept| content_tag(:li, "stuff...")}.join
end
end
def test_if_complete(test_subject)
test_subject.id rescue nil
end
#
def test_if_complete(part, current_part)
unless current_part.to_s == ""
part.concepts.map { |concept| content_tag(:li, "stuff...")}.join
end
end
#
def test_if_complete(part, current_part)
unless current_part.nil?
part.concepts.map { |concept| content_tag(:li, "stuff...")}.join
end
end
#
PS, a truncated line at each of the above values:
part.concepts.map { |concept| content_tag(:li, "Concept: “" + concept.title + "”", :class => "one_concept") + content_tag(:li, "Attached images (" + concept.images.size.to_s + ")", :class => "all_images") + content_tag(:li, "Attached docs (XX)", :class => "all_docs")}.join
source to share
The test current_part.to_s == ""
returns true
on my ruby โโsystem when current_part
- nil
. Unlike some other languages, you can say nil.to_s
and nil.nil?
and make them work. I think there is something else that is causing the problem. Can you show more code?
(My tests were in ruby โโ1.8.6)
Edit. In hindsight, what usually causes the above error is a type expression "text" + nil
, not nil.to_s
. Do you have something like that?
source to share
The problem is your truncated line, where concept.title matches plus.
When you do
"Foo" + some_obj.some_attr
and some_attr on an object is nil, Ruby won't autocopy it to string. This happens a lot (!) Because Rails injects NULL into the database for nils. The workarounds are string evaluations:
"Foo #{some_obj.attr_that_can_be_nil}"
wildcard substitution (automatically truncates zero)
"Foo %s" % some_obj.attr_that_can_be_nil
or array concatenation (idem ditto)
["Foo ", some_obj.attr_that_can_be_nil].join
The reason you couldn't find it is because your "truncated line" deserves to have 5-6 lines expanded properly, so it will be much easier for you to identify the problem.
You don't need "and friends" in rims, just type it literally, since Rails is UTF-8 anyway. Also, when you pass stuff to the handler methods, you can convert that thing to & ldquo; completely not what you want (if helpers avoid entities - I don't remember if they do, but Builder certainly does).
source to share
If the object is null, you cannot use any of its members, because the object itself does not exist. So the comparison must be object and nil, not element of object and nil.
It's like a null pointer exception.
You should use something like
x = get_some_object if x.nil?
to initialize the variable x if it is not initialized.
source to share
Tobias is right. You cannot access any member of an object if it is null (since it doesn't exist). You must check for nil before performing any operation or before accessing any varible member or function.
In cpp, it's like this:
if (! current_part) {perform operation}
`This is a very common NPE (Null Pointer Exception) in almost every programming language.
source to share
Is this a local variable in some partial? if so, then even execution current_part.nil?
will result in an error if the variable is not partially passed.
to overcome this:
counter_part = defined?(counter_part) ? : counter_part : nil
BTW: Usually Ruby looks for an assignment operator to determine if something is variable - if no name has been assigned, then Ruby assumes the name is a method call, so executing the following statement will throw an error if x
not initialized:
irb(main):001:0> puts "yes nil" if x.nil?
#=>NameError: undefined local variable or method `x' for main:Object
source to share