简单的电子表格不正确地加载一个XML文件的ruby,但正常工作在IRB

我目前正试图打开和parsing这个XML文件使用ruby2.1.1。 直接的方法是使用简单的电子表格gem,这似乎不适用于这个特定的电子表格(和其他几个):

require 'simple-spreadsheet' s=SimpleSpreadsheet::Workbook.read('151.xls') puts s.last_row #prints 5 

但是,当我复制并粘贴到IRB这个确切的代码,我得到正确的答案

 2.1.1 :001 > require 'simple-spreadsheet' => true 2.1.1 :002 > s=SimpleSpreadsheet::Workbook.read('151.xls') => #prints the entire contents of the spreadsheet 2.1.1 :003 > s.last_row => 154 

当使用Roo时,会出现同样的情况(这是可以预料的,因为简单电子表格使用Roo打开.xls文件):

 require 'roo' s=Roo::Excel.new('151.xls') puts s.last_row #prints 5, should print 154 

而在irb上

 2.1.1 :001 > require 'simple-spreadsheet' => true 2.1.1 :002 > s=Roo::Excel.new('151.xls') => #prints the entire contents of the spreadsheet 2.1.1 :003 > s.last_row => 154 

进一步挖掘,我尝试使用电子表格,因为它需要Roo的excel.rb文件:

 require 'spreadsheet' Spreadsheet.open('151.xls') do |book| rows=0 book.worksheet(0).each do |row| rows+=1 end puts rows#prints 5 end 

然而,这是奇怪的地方(呃); 当我复制并粘贴到irb最后的代码,我得到

 2.1.1 :001 > require 'spreadsheet' => true 2.1.1 :002 > Spreadsheet.open('152.xls') do |book| 2.1.1 :003 > rows=0 2.1.1 :004?> book.worksheet(0).each do |row| 2.1.1 :005 > rows+=1 2.1.1 :006?> end 2.1.1 :007?> puts rows 2.1.1 :008?> end 5 => nil 

我应该补充说,gem不只是印刷5; 该行下面的每个单元格返回nil; 他们实际上停止parsing这个特定的行之后的文件。

所以这里是我的问题:拳头,为什么irb行为比ruby不同? 其次,为什么没有任何gem加载整个电子表格? 第三,我能做些什么来解决这个问题?

谢谢你的帮助

这是我见过的最奇怪的问题之一。 回答你的问题:

首先,为什么irb的performance与ruby不同?

IRB是一个用ruby编写的工具,与直接执行ruby不同。 其中一个主要的区别是IRB在启动时可以设置不同的选项。 你可以在源代码中看到不同的标志, 这个页面对这些标志的含义有很好的描述。

你看到的不一致的罪魁祸首是--noinspect选项,运行irb --noinspect和执行你的代码应该给你像运行ruby程序(你只看到5行)相同的奇怪的行为。 这是因为irb默认在执行的每一行调用inspect,所以当你调用s=SimpleSpreadsheet::Workbook.read('151.xls')它实际上就像在一个ruby程序中调用它:

 s = SimpleSpreadsheet::Workbook.read('151.xls') s.inspect 

为什么叫s.inspect重要? 继续阅读…

其次,为什么没有任何gem加载整个电子表格?

这是最难回答的问题,我还没有find100%,但希望90%的解释是足够好的。 总之,你提到的所有gem都依赖于spreadsheetgem。 在这个特定的设置(我不认为它的devise总是这样工作)的怪癖/错误之一似乎是它对inspect方法的依赖。 如果你在工作表上调用inspect ,那么比起你不打电话的话,它会持续更多的价值。 也就是说,如果你不调用它只是读取文件的一部分(或者读取其中的一部分,而忽略其余部分,我不确定),但是如果你打电话来inspect它完全读取文件。

第三,我能做些什么来解决这个问题?

正如我之前提到的,手动调用inspect应该读取整个文件:

 s = SimpleSpreadsheet::Workbook.read('151.xls') s.inspect