Stuck on silly nil issue

N

Nick Wild

Banging my head on the desk over this..

I'll try to generalize my issue down to this scenario. Since I remember
always using cars back in programming classes here it goes...


cars["yugo"].status["available"] = 2


Some thing like this is working perfectly...

if cars["yugo"].status["available"]
puts "There are" + cars["yugo"].status["available"].to_i + "yugos
available"
end
if cars["kia"].status["available"]
puts "There are" + cars["kia"].status["available"].to_i + "kia
available"
end

I get "There are 2 yugos available"



But when I do this....

cars_to_scan = ["yugo", "kia"]
cars_to_scan.each { |carbrand|
if cars[carbrand].status["available"]
puts cars["yugo"].status["available"].to_i + carbrand + "available"
}


I hit: You have a nil object when you didn't expect it!
You might have expected an instance of ActiveRecord::Base.
The error occurred while evaluating nil.attributes

So I tried

if cars[carbrand.to_s].status["available"]
and also this:
unless cars[carbrand.to_s].status["available"].nil?

same error

I don't understand why I can use the string directly but when I try
indirectly it's hitting this error and why I'm getting a nil error when
I'm trying to use the if to check if the object is not nil.

I'm still really baffled by certain things in ruby. Thanks in advance
for any tips or pointers. I'm sorry for the newbie question but this is
one of those dig through google and books and still come up ready to
pull your hair out little niggling things.

Thanks!
 
R

Robert Klemme

2009/8/25 Nick Wild said:
Banging my head on the desk over this..

I'll try to generalize my issue down to this scenario. Since I remember
always using cars back in programming classes here it goes...


cars["yugo"].status["available"] =3D 2


Some thing like this is working perfectly...

if cars["yugo"].status["available"]
=A0 puts "There are" + cars["yugo"].status["available"].to_i + "yugos
available"
end
if cars["kia"].status["available"]
=A0 puts "There are" + cars["kia"].status["available"].to_i + "kia
available"
end

I get "There are 2 yugos available"



But when I do this....

cars_to_scan =3D ["yugo", "kia"]
cars_to_scan.each { |carbrand|
=A0if cars[carbrand].status["available"]
=A0 =A0puts cars["yugo"].status["available"].to_i + carbrand + "available= "
}


I hit: You have a nil object when you didn't expect it!
You might have expected an instance of ActiveRecord::Base.
The error occurred while evaluating nil.attributes

So I tried

if cars[carbrand.to_s].status["available"]
and also this:
unless cars[carbrand.to_s].status["available"].nil?

same error

I don't understand why I can use the string directly but when I try
indirectly it's hitting this error and why I'm getting a nil error when
I'm trying to use the if to check if the object is not nil.

I'm still really baffled by certain things in ruby. Thanks in advance
for any tips or pointers. I'm sorry for the newbie question but this is
one of those dig through google and books and still come up ready to
pull your hair out little niggling things.

Look at your line that starts with "puts" - it's just a silly copy and
paste error. :)

Note: if you need to access a single object multiple times in the
block, it is more efficient and probably also more readable to just
pull it once.

Cheers

robert

--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 
N

Nick Wild

Robert - Thanks for taking a look!

Maybe I should have used my actual code instead of trying to write up an
example. The lack of end on my if in the example wasn't the issue.
Here's the actual block with content sanitized.

Where xmldoc is a REXML object I'm using without problem elsewhere in
this code.

The IF line below is where I hit the problems

types = ["foo", "bar", "stuff", "other", "favorite"]
conditions = ["up", "down", "marginal"]


types.each { |@scan_type|
conditions.each { |@scan_conditions|
if xmldoc.elements[@scan_type].attributes[@scan_conditions]
count_to_add =
site.elements[@scan_type].attributes[@scan_conditions].to_i
addtodb(siteToSave.id, scan_type, scan_conditions,count_to_add)
end
}
}
 
R

Robert Klemme

Nick, please do not top post.

2009/8/25 Nick Wild said:
Robert - Thanks for taking a look!

Maybe I should have used my actual code instead of trying to write up an
example. The lack of end on my if in the example wasn't the issue.

I actually meant the use of a constant vs. the local variable from the
iteration:

puts cars["yugo"] ...
Here's the actual block with content sanitized.

Where xmldoc is a REXML object I'm using without problem elsewhere in
this code.

The IF line below is where I hit the problems

types =3D ["foo", "bar", "stuff", "other", "favorite"]
conditions =3D ["up", "down", "marginal"]


types.each { |@scan_type|
=A0conditions.each { |@scan_conditions|
=A0 if xmldoc.elements[@scan_type].attributes[@scan_conditions]
=A0 =A0count_to_add =3D
site.elements[@scan_type].attributes[@scan_conditions].to_i
=A0 =A0addtodb(siteToSave.id, scan_type, scan_conditions,count_to_add)
=A0 end
=A0}
}

You are abusing instance variables. Please get rid of all the @'s as
they have no use in this case.

Then, #elements returns a collection of elements - you need to iterate
them if you want to get at each elements attributes. I believe though
that there are XPath expressions which directly select attributes. I
am unsure whether REXML supports them. See:

http://www.w3schools.com/xpath/
http://www.zvon.org/xxl/XPathTutorial/General/examples.html

My previous remark about not fetching things twice is even more valid
with REXML. By refactoring to only fetch certain things once your
code will become more readable and more efficient.

Kind regards

robert

--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 
N

Nick Wild

Hopefully this will not top post.

Yes, sorry my example was so hackish I was churning a bunch of code
trying to zero in on the issue. I'll switch over to iterating through
with a single fetch per pass and shed the ivars.

For what it is worth I did just figure out that when I test if
xmldoc.elements[@scan_type] is nil first this code works albeit
inefficiently as noted. I was foolishly thinking that nil.nil would eval
as false for the if.

Thank you again for your advice.

Cheers,

Nick
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,754
Messages
2,569,522
Members
44,995
Latest member
PinupduzSap

Latest Threads

Top