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

  1. require 'rubygems'
  2. require 'gruff'
  3.  
  4.   def basic_graph()
  5.     g = Gruff::Line.new
  6.     g.theme = {
  7.       :colors => ['#7F0099', '#2F85ED', '#2FED09','#EC962F'],
  8.       :marker_color => '#aaa',
  9.       :background_colors => ['#E8E8E8','#B9FD6C']
  10.     }
  11.     g.hide_title = true
  12.  
  13.     g.legend_font_size = 12
  14.     g.marker_font_size = 16
  15.     g.hide_dots = false
  16.  
  17.     return g
  18.   end
  19.  
  20.  
  21.   def bmi(params={})
  22.     g = basic_graph()
  23.  
  24.     g.y_axis_label = 'BMI'
  25.  
  26.     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]
  27.  
  28.     g.data( 'BMI', bmis )
  29.     g.hide_legend = true
  30.     return g
  31.   end
  32.  
  33.  
  34. g=bmi
  35. g.write 'graph.jpg'

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.

  1. def label(value)
  2.   if (@spread.to_f % @marker_count.to_f == 0) || !@y_axis_increment.nil?
  3.     return value.to_i.to_s
  4.   end
  5.   if @spread > 10.0
  6.     sprintf("%0i", value)
  7.   elsif @spread >= 3.0
  8.     sprintf("%0.2f", value)
  9.   else
  10.     value.to_s
  11.   end
  12. end

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

  1. (@spread.to_f % @marker_count.to_f == 0) || !@y_axis_increment.nil?

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 *