Hi,
I am seeing some odd behavior that look to me to like it could be a bug
in Ruby. Being new to the language, however, I wanted to see if there
was another explanation. I am using Ruby 1.8.4 on an Intel Mac. The
code at the bottom of this message is an excerpt from a class in a
larger script. It is using DBI to pull 10 fields from a MySQL database.
The first 9 are integers (tinyint(4) in the database) and the last is a
string (varchar(255) in the database). When I run the below program as
is, the puts outputs:
Info[0] class: String
Info[0] value: 0
Info[0] class: String
Info[0] value: 0
.
.
.
However, if I uncomment the ‘info.each’ line, I get:
Info[0] class: Fixnum
Info[0] value: 0
0
Info[0] class: Fixnum
Info[0] value: 0
0
.
.
.
So, it seams that just printing out the value in an ‘each’ loop causes
it to change from a String to a Fixnum throughout the code segment. The
break statement makes no difference (it just reduces the output for the
purpose of posting here). It is my understanding that the MySQL driver
for DBI should coerce the objects to numbers since that is their type in
the database. However, regardless of what type they start as, I don’t
understand how adding an each loop with a print in it can change the
type. Also, I can’t seem to reproduce this behavior in a small test
program. I do know that the database queries are successful and are
returning the proper values. Does anyone have any ideas? Is this a bug
or is there some subtlety of type inferencing that I am missing?
@sthVulnID.fetch do |id|
ids.push(id[0])
begin
@sthVulnInfo.execute(id[0])
rescue DBI::DatabaseError => e
puts “An error occurred getting vulnerability info”
puts “Variables: name:”#{name}" k:"#{k}" v:"#{v}""
puts “Error code: #{e.err}”
puts “Error message: #{e.errstr}”
exit
end
info = @sthVulnInfo.fetch_array
puts "Info is: #{info[0].class}"
info.each { |newval| puts “#{newval.class}”; break }
newVuln.addInfo('osvdb-location', 'physical') if ( info[0] == 1 )
newVuln.addInfo('osvdb-location', 'local') if ( info[1] == 1 )
newVuln.addInfo('osvdb-location', 'remote') if ( info[2] == 1 )
newVuln.addInfo('osvdb-location', 'dialup') if ( info[3] == 1 )
newVuln.addInfo('osvdb-location', 'unknown') if ( info[4] == 1 )
newVuln.addInfo('osvdb-impact', 'confidentiality') if ( info[5] ==
1 )
newVuln.addInfo(‘osvdb-impact’, ‘integrity’) if ( info[6] == 1 )
newVuln.addInfo(‘osvdb-impact’, ‘availability’) if ( info[7] == 1
)
newVuln.addInfo(‘osvdb-impact’, ‘unknown’) if ( info[8] == 1 )
newVuln.addInfo(‘osvdb-title’, info[9])
end