Why I like JRuby

Some days ago Tom forwarded me an email from Mikael Lammentausta. Mikael found an issue with rmagick4j. Using this Mikael’s script

[ruby]
require ‘rubygems’
require ‘gruff’

def basic_graph()
g = Gruff::Line.new
g.theme = {
:colors => [‘#7F0099’, ‘#2F85ED’, ‘#2FED09′,’#EC962F’],
:marker_color => ‘#aaa’,
:background_colors => [‘#E8E8E8′,’#B9FD6C’]
}
g.hide_title = true

g.legend_font_size = 12
g.marker_font_size = 16
g.hide_dots = false

return g
end

def bmi(params={})
g = basic_graph()

g.y_axis_label = ‘BMI’

bmis = [24.3, 23.9, 23.7, 23.7, 23.6, 23.9, 23.6, 23.7, 23.4, 23.4, 23.4, 22.9]

g.data( ‘BMI’, bmis )
g.hide_legend = true
return g
end

g=bmi
g.write ‘graph.jpg’
[/ruby]

You get two different outputs.

MRI-generated
MRI-generated
JRuby
JRuby

As you may see, the numbers are wrong in JRuby… or not.

Looking at gruff code, I saw the problem was in the label method.

[ruby]
def label(value)
if (@spread.to_f % @marker_count.to_f == 0) || !@y_axis_increment.nil?
return value.to_i.to_s
end
if @spread > 10.0
sprintf(“%0i”, value)
elsif @spread >= 3.0
sprintf(“%0.2f”, value)
else
value.to_s
end
end
[/ruby]

The problem can be found in line 10. With a right input, you can make

[ruby]
(@spread.to_f % @marker_count.to_f == 0) || !@y_axis_increment.nil?
[/ruby]

false and have a @spread < 3.0. Then look at this code: [ruby] i = 23.599999999999998 puts i [/ruby] In JRuby, you get what you expect 23.599999999999998 but, in MRI, you get 23.6. So, that was the problem. JRuby is more precise than MRI.

NOTE:
jruby 1.1.5 (ruby 1.8.6 patchlevel 114) (2008-11-03 rev 7996) [i386-java]
ruby 1.8.6 (2008-03-03 patchlevel 114) [universal-darwin9.0]

Author: Serabe

Mathematician, and Ruby and JavaScript programmer. Sometimes I speak at conferences and local meetups.

Leave a Reply

Your email address will not be published. Required fields are marked *