1

If I decide to use Rationals in Ruby for a console application, but don't want them displayed as a fraction, is there an idiomatic way to specify they should be displayed in decimal notation?

Options I know about include:

 fraction = Rational(1, 2)
 puts "Use to_f: #{fraction.to_f}"
 puts(sprintf("Use sprintf %f", fraction))
 class Rational
   def to_s
     to_f.to_s
   end
 end
 puts "Monkey patch Rational#to_s: #{fraction}"

Are there any alternatives?

Andrew Grimm
  • 78,473
  • 57
  • 200
  • 338
  • I was taught by your question that `to_f.to_s` and `sprintf("%f", self)` default to different accuracy. If you want a control over the accuracy, it's better idea to define `Rational#to_s` using `sprintf` or `%` rather than `to_f.to_s`? – sawa Mar 31 '11 at 03:40
  • I think you should say more about the context. "Don't want them as a fraction" sounds pretty generic and arbitrary. What are you writing? Rails app? Console app? A gem? – Mladen Jablanović Mar 31 '11 at 16:58

1 Answers1

5

You can use %g in the sprintf to get the 'right' precision:

puts "%g" % Rational(1,2)
#=> 0.5

I'd personally monkey patch rational as you have, but then I'm a fan of monkey patching. Overriding the built-in to_s behavior seems entirely appropriate for a console application.

Perhaps you have another alternative where you write your own console that defines Object#to_console to call to_s, and then you could monkey patch in your own Rational#to_console instead. That extra effort would make it safer for the 0.1% chance that some library is using Rational#to_s already in a way that will break with your patch.

Phrogz
  • 296,393
  • 112
  • 651
  • 745