最近开始关注Rubinius。这是一个Ruby的虚拟机实现,它追求的目标是要用Ruby来实现Ruby,所以很吸引大家的眼球。目前,Rubinius还处于比较原始的阶段,还不能跑Rails之类的应用。
Rubinius的开发模式也很有趣。开发者首先是写了一大堆spec,再修改代码使这些spec通过,基本上是TDD的路子。现在不少工作都是在完善这些spec,而不是完善功能本身。因为Ruby本身并没有明确定义的语言规范,所以这些spec首先得在MRI上通过后,再用于Rubinius。开发者甚至想把完善后的spec最为Ruby的语言规范和标准,用于其他Ruby实现的开发。
今天我就跑了跑目前已经稳定的spec,结果String#to_f失败了。仔细看了一下,(1.0 / "-0".to_f).to_s.should == "-Infinity"这句失败了,结果是“Infinity”,而不是希望的“-Infinity”。再细看下去是"-0".to_f返回的是“0.0”,而在MRI里则返回“-0.0”。Rubinius的String#to_f和MRI一样也是用C语言实现的,基本上就是调用strtod函数。我又在我的PowerBook上试了一样,是对的。所以问题应该出在strtod函数上。
通过Google Code Search搜了一把,发现很多软件,包括MRI,都提供自己的strtod的实现,看来就是为了解决这个正0和负0的返回值问题。它们提供的实现应该是BSD的实现,苹果的Mac OS X也是从BSD发展而来,所以能通过。这应该是我第一次直面这种兼容性问题。
后记
今天发现这个Bug确实是strtod()的问题,具体可以看这里。Revision 1.25已经修改了这个错误,Lighthouse里也发现了这个问题。看来我的Gutsy是解决不了这个问题了,只有等升级到Hardy(>glibc 2.6.1)了。