diff --git a/CHANGELOG b/CHANGELOG index a1a295fa..4a5654c3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -8,6 +8,7 @@ * Accept the tmpdir_root option in Roo::Excelx * Change the tmpdir prefix from oo_ to roo_ * In Excelx, load styles, shared strings and the workbook lazily. Leave the tmpdir open so that reading may take place after initialize. The OS will be responsible for cleaning it up. + * Lazily initialize @default_sheet, to avoid reading the sheets earlier than necessary. Use the #default_sheet accessor instead. * bugfixes * Fix that paths with spaces in them would fail with diff --git a/lib/roo/base.rb b/lib/roo/base.rb index 5cf3137b..ebb6b8c7 100644 --- a/lib/roo/base.rb +++ b/lib/roo/base.rb @@ -21,7 +21,7 @@ class Roo::Base TEMP_PREFIX = "roo_" LETTERS = ('A'..'Z').to_a - attr_reader :default_sheet, :headers + attr_reader :headers # sets the line with attribute names (default: 1) attr_accessor :header_line @@ -92,7 +92,10 @@ def initialize(filename, options={}, file_warning=:error, tmpdir=nil) @last_column = {} @header_line = 1 - @default_sheet = self.sheets.first + end + + def default_sheet + @default_sheet ||= self.sheets.first end # sets the working sheet in the document @@ -116,7 +119,7 @@ def last_column_as_letter(sheet=nil) # returns the number of the first non-empty row def first_row(sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet read_cells(sheet) @first_row[sheet] ||= begin @@ -131,7 +134,7 @@ def first_row(sheet=nil) # returns the number of the last non-empty row def last_row(sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet read_cells(sheet) @last_row[sheet] ||= begin @@ -146,7 +149,7 @@ def last_row(sheet=nil) # returns the number of the first non-empty column def first_column(sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet read_cells(sheet) @first_column[sheet] ||= begin @@ -161,7 +164,7 @@ def first_column(sheet=nil) # returns the number of the last non-empty column def last_column(sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet read_cells(sheet) @last_column[sheet] ||= begin @@ -178,7 +181,7 @@ def last_column(sheet=nil) # you can add additional attributes with the prefix parameter like: # oo.to_yaml({"file"=>"flightdata_2007-06-26", "sheet" => "1"}) def to_yaml(prefix={}, from_row=nil, from_column=nil, to_row=nil, to_column=nil,sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet return '' unless first_row # empty result if there is no first_row in a sheet from_row ||= first_row(sheet) @@ -210,7 +213,7 @@ def to_yaml(prefix={}, from_row=nil, from_column=nil, to_row=nil, to_column=nil, # write the current spreadsheet to stdout or into a file def to_csv(filename=nil,sheet=nil,separator=',') - sheet ||= @default_sheet + sheet ||= default_sheet if filename File.open(filename,"w") do |file| write_csv_content(file,sheet,separator) @@ -228,7 +231,7 @@ def to_csv(filename=nil,sheet=nil,separator=',') def to_matrix(from_row=nil, from_column=nil, to_row=nil, to_column=nil,sheet=nil) require 'matrix' - sheet ||= @default_sheet + sheet ||= default_sheet return Matrix.empty unless first_row from_row ||= first_row(sheet) @@ -267,7 +270,7 @@ def find(*args) # :nodoc # returns all values in this row as an array # row numbers are 1,2,3,... like in the spreadsheet def row(rownumber,sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet read_cells(sheet) first_column(sheet).upto(last_column(sheet)).map do |col| cell(rownumber,col,sheet) @@ -280,7 +283,7 @@ def column(columnnumber,sheet=nil) if columnnumber.class == String columnnumber = self.class.letter_to_number(columnnumber) end - sheet ||= @default_sheet + sheet ||= default_sheet read_cells(sheet) first_row(sheet).upto(last_row(sheet)).map do |row| cell(row,columnnumber,sheet) @@ -290,7 +293,7 @@ def column(columnnumber,sheet=nil) # set a cell to a certain value # (this will not be saved back to the spreadsheet file!) def set(row,col,value,sheet=nil) #:nodoc: - sheet ||= @default_sheet + sheet ||= default_sheet read_cells(sheet) row, col = normalize(row,col) cell_type = @@ -307,14 +310,14 @@ def set(row,col,value,sheet=nil) #:nodoc: # reopens and read a spreadsheet document def reload - ds = @default_sheet + ds = default_sheet reinitialize self.default_sheet = ds end # true if cell is empty def empty?(row, col, sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet read_cells(sheet) row,col = normalize(row,col) contents = cell(row, col, sheet) @@ -395,8 +398,8 @@ def method_missing(m, *args) # access different worksheets by calling spreadsheet.sheet(1) # or spreadsheet.sheet('SHEETNAME') def sheet(index,name=false) - @default_sheet = String === index ? index : self.sheets[index] - name ? [@default_sheet,self] : self + default_sheet = String === index ? index : self.sheets[index] + name ? [default_sheet,self] : self end # iterate through all worksheets of a document @@ -438,7 +441,7 @@ def each(options={}) if options[:clean] options.delete(:clean) @cleaned ||= {} - @cleaned[@default_sheet] || clean_sheet(@default_sheet) + @cleaned[default_sheet] || clean_sheet(default_sheet) end if options[:header_search] @@ -640,12 +643,12 @@ def header_index(query) end def set_value(row,col,value,sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet @cell[sheet][[row,col]] = value end def set_type(row,col,type,sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet @cell_type[sheet][[row,col]] = type end diff --git a/lib/roo/csv.rb b/lib/roo/csv.rb index 082b98a2..cb2e6ef2 100644 --- a/lib/roo/csv.rb +++ b/lib/roo/csv.rb @@ -25,13 +25,13 @@ def sheets end def cell(row, col, sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet read_cells(sheet) @cell[normalize(row,col)] end def celltype(row, col, sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet read_cells(sheet) @cell_type[normalize(row,col)] end @@ -69,7 +69,7 @@ def each_row(options, &block) end def read_cells(sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet return if @cells_read[sheet] @first_row[sheet] = 1 @last_row[sheet] = 0 diff --git a/lib/roo/excelx.rb b/lib/roo/excelx.rb index 65ddb171..64637a02 100644 --- a/lib/roo/excelx.rb +++ b/lib/roo/excelx.rb @@ -144,7 +144,7 @@ def method_missing(m,*args) # is method name a label name read_labels if @label.has_key?(m.to_s) - sheet ||= @default_sheet + sheet ||= default_sheet read_cells(sheet) row,col = label(m.to_s) cell(row,col) @@ -155,7 +155,7 @@ def method_missing(m,*args) end def sheet_for(sheet) - sheet ||= @default_sheet + sheet ||= default_sheet validate_sheet!(sheet) n = self.sheets.index(sheet) @@ -167,7 +167,7 @@ def sheet_for(sheet) # (1,1), (1,'A'), ('A',1), ('a',1) all refers to the # cell at the first line and first row. def cell(row, col, sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet sheet_object = sheet_for(sheet) read_cells(sheet) row,col = key = normalize(row,col) @@ -188,7 +188,7 @@ def cell(row, col, sheet=nil) # Returns nil if there is no formula. # The method #formula? checks if there is a formula. def formula(row,col,sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet read_cells(sheet) row,col = normalize(row,col) @formula[sheet][[row,col]] && @formula[sheet][[row,col]] @@ -198,7 +198,7 @@ def formula(row,col,sheet=nil) # returns each formula in the selected sheet as an array of elements # [row, col, formula] def formulas(sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet read_cells(sheet) if @formula[sheet] @formula[sheet].map do |coord, formula| @@ -227,7 +227,7 @@ def underline? # Given a cell, return the cell's style def font(row, col, sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet read_cells(sheet) row,col = normalize(row,col) style_definitions[@style[sheet][[row,col]].to_i] @@ -242,7 +242,7 @@ def font(row, col, sheet=nil) # * :time # * :datetime def celltype(row,col,sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet read_cells(sheet) sheet_object = sheet_for(sheet) @@ -261,7 +261,7 @@ def celltype(row,col,sheet=nil) # * :string # Note: this is only available within the Excelx class def excelx_type(row,col,sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet read_cells(sheet) row,col = normalize(row,col) @excelx_type[sheet][[row,col]] @@ -270,7 +270,7 @@ def excelx_type(row,col,sheet=nil) # returns the internal value of an excelx cell # Note: this is only available within the Excelx class def excelx_value(row,col,sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet read_cells(sheet) row,col = normalize(row,col) @excelx_value[sheet][[row,col]] @@ -278,7 +278,7 @@ def excelx_value(row,col,sheet=nil) # returns the internal format of an excel cell def excelx_format(row,col,sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet read_cells(sheet) row,col = normalize(row,col) style_format(@style[sheet][[row,col]]).to_s @@ -294,7 +294,7 @@ def sheets # shows the internal representation of all cells # for debugging purposes def to_s(sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet read_cells(sheet) @cell[sheet].inspect end @@ -315,7 +315,7 @@ def label(labelname) # Returns an array which all labels. Each element is an array with # [labelname, [row,col,sheetname]] def labels - # sheet ||= @default_sheet + # sheet ||= default_sheet # read_cells(sheet) read_labels @label.map do |label| @@ -491,7 +491,7 @@ def read_cell_from_xml(sheet, cell_xml) # read all cells in the selected sheet def read_cells(sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet validate_sheet!(sheet) return if @cells_read[sheet] diff --git a/lib/roo/open_office.rb b/lib/roo/open_office.rb index 0666f6c9..731854b8 100644 --- a/lib/roo/open_office.rb +++ b/lib/roo/open_office.rb @@ -67,7 +67,7 @@ def method_missing(m,*args) # (1,1), (1,'A'), ('A',1), ('a',1) all refers to the # cell at the first line and first row. def cell(row, col, sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet read_cells(sheet) row,col = normalize(row,col) if celltype(row,col,sheet) == :date @@ -81,7 +81,7 @@ def cell(row, col, sheet=nil) # Returns nil if there is no formula. # The method #formula? checks if there is a formula. def formula(row,col,sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet read_cells(sheet) row,col = normalize(row,col) @formula[sheet][[row,col]] @@ -91,7 +91,7 @@ def formula(row,col,sheet=nil) # returns each formula in the selected sheet as an array of elements # [row, col, formula] def formulas(sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet read_cells(sheet) if @formula[sheet] @formula[sheet].each.collect do |elem| @@ -120,7 +120,7 @@ def underline? # Given a cell, return the cell's style def font(row, col, sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet read_cells(sheet) row,col = normalize(row,col) style_name = @style[sheet][[row,col]] || @style_defaults[sheet][col - 1] || 'Default' @@ -136,7 +136,7 @@ def font(row, col, sheet=nil) # * :time # * :datetime def celltype(row,col,sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet read_cells(sheet) row,col = normalize(row,col) if @formula[sheet][[row,col]] @@ -162,7 +162,7 @@ def officeversion # shows the internal representation of all cells # mainly for debugging purposes def to_s(sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet read_cells(sheet) @cell[sheet].inspect end @@ -199,7 +199,7 @@ def labels(sheet=nil) # returns the comment at (row/col) # nil if there is no comment def comment(row,col,sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet read_cells(sheet) row,col = normalize(row,col) return nil unless @comment[sheet] @@ -209,7 +209,7 @@ def comment(row,col,sheet=nil) # returns each comment in the selected sheet as an array of elements # [row, col, comment] def comments(sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet read_comments(sheet) unless @comments_read[sheet] if @comment[sheet] @comment[sheet].each.collect do |elem| @@ -277,7 +277,7 @@ def set_cell_values(sheet,x,y,i,v,value_type,formula,table_cell,str_v,style_name # some content #++ def read_cells(sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet validate_sheet!(sheet) return if @cells_read[sheet] diff --git a/test/test_generic_spreadsheet.rb b/test/test_generic_spreadsheet.rb index cbb26160..53301f8d 100644 --- a/test/test_generic_spreadsheet.rb +++ b/test/test_generic_spreadsheet.rb @@ -15,12 +15,12 @@ def read_cells(sheet=nil) end def cell(row, col, sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet @cell[sheet][[row,col]] end def celltype(row, col, sheet=nil) - sheet ||= @default_sheet + sheet ||= default_sheet @cell_type[sheet][[row,col]] end diff --git a/test/test_roo.rb b/test/test_roo.rb index 7d34bcdf..d2bac112 100644 --- a/test/test_roo.rb +++ b/test/test_roo.rb @@ -1003,18 +1003,18 @@ def test_file_warning_error def test_file_warning_warning if OPENOFFICE - assert_raises(Errno::ENOENT) { - Roo::OpenOffice.new(File.join(TESTDIR,"numbers1.xlsx"), - packed: false, - file_warning: :warning) - } + assert_raises(Errno::ENOENT) { + Roo::OpenOffice.new(File.join(TESTDIR,"numbers1.xlsx"), + packed: false, + file_warning: :warning) + } end if EXCELX - assert_raises(Errno::ENOENT) { - Roo::Excelx.new(File.join(TESTDIR,"numbers1.ods"), - packed: false, - file_warning: :warning) - } + assert_nothing_raised { + Roo::Excelx.new(File.join(TESTDIR,"numbers1.ods"), + packed: false, + file_warning: :warning) + } end end