Stuck on silly nil issue

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!

···

--
Posted via http://www.ruby-forum.com/.

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

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

···

2009/8/25 Nick Wild <nickwild@gmail.com>:

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.

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

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
  }
}

Robert Klemme wrote:

···

2009/8/25 Nick Wild <nickwild@gmail.com>:

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. :slight_smile:

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

--
Posted via http://www.ruby-forum.com/\.

Nick, please do not top post.

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 = ["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
}
}

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

···

2009/8/25 Nick Wild <nickwild@gmail.com>:

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

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

···

--
Posted via http://www.ruby-forum.com/.