いけがみです。

>   (@i1.hash + @i2).hash
> とかの方がよいのかも

Rational だと、reduce してから hash をとらないと同一性が保証できません。
現在の Rational でも、 eql? で true を返すのに hash が異なっています。

eql? が約分して同じかどうかを確認している以上、
hash でも約分する必要がありそうです。
でもそうすると hash の計算コストが高いですね。

irb(main):001:0> require 'rational'
true
irb(main):002:0> a = Rational.new(1, 2)
Rational(1, 2)
irb(main):003:0> b = Rational.new(2, 4)
Rational(2, 4)
irb(main):004:0> a.eql?(b)
true
irb(main):005:0> a.hash == b.hash
false

--
池上 大介
Daisuke IKEGAMI <daisu-ik / is.aist-nara.ac.jp>
奈良先端科学技術大学院大学 情報科学研究科
情報処理学専攻 情報基礎学講座 関研究室