csv_madness 0.0.4 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4f4f9b06af750b458f7eb43b10053dfce2b60a69cc55ea4410d4466c72680f0c
4
+ data.tar.gz: 23ddbf472f0b52973769e21eb72939622bee0e5b13e43e8c292ae28203106145
5
+ SHA512:
6
+ metadata.gz: 1e44f1666c4118cf68a16f254ea5ad8808f9a0036b346755d187c74baf24a65cff718323d81741cd5478b036fcea3518daa3b2b5f72f6de2bf89b3b435392de8
7
+ data.tar.gz: b44d0fa470ec59317f5a93b0e73d1ec6a032f300083734e2b0aef27b2077b51303dce1b504e77102e6cfb5f79cc2c229d136d4a5d7eca049402bb88e740e711a
data/CHANGELOG.markdown CHANGED
@@ -1,17 +1,35 @@
1
+ Changelog
2
+ =========
3
+
4
+ 0.0.6
5
+ -----
6
+
7
+ * CsvMadness::Builder added (easily generate spreadsheets from an array of objects)
8
+
9
+
10
+ 0.0.5
11
+ -----
12
+
13
+ * Splitting spreadsheets, creating blank copies of spreadsheets, adding/removing records.
14
+ * Convert records to hashes/arrays.
15
+ * Created a dependency on `fun_with_testing`.
16
+ * CsvMadness.version
17
+
18
+
1
19
  0.0.4
2
- =====
20
+ -----
3
21
 
4
22
  * Fixed serious bug for default column names. record.middle_name instead of record.middlename
5
23
  * Spreadsheet can be re-read from file by calling @sheet.reload_spreadsheet(opts)
6
24
 
7
25
 
8
26
  0.0.3
9
- =====
27
+ -----
10
28
 
11
29
  * Feature: can add and drop columns from spreadsheets
12
30
 
13
31
 
14
32
  0.0.2
15
- =====
33
+ -----
16
34
 
17
35
  * Aw, hell. I don't remember.
data/Gemfile CHANGED
@@ -6,12 +6,14 @@ source "http://rubygems.org"
6
6
  # Add dependencies to develop your gem here.
7
7
  # Include everything needed to run rake, tests, features, etc.
8
8
 
9
- gem "fun_with_files"
10
-
11
9
  group :development do
12
- gem "shoulda", ">= 0"
13
- gem "rdoc", "~> 3.12"
14
- gem "bundler", "~> 1.3.0"
15
- gem "jeweler", "~> 1.8.4"
16
- gem "debugger"
10
+ # gem "shoulda", ">= 3.5"
11
+ # gem "rdoc", "~> 3.12"
12
+ # gem "bundler", "~> 1.5"
13
+ # gem "jeweler", "~> 2"
14
+ gem "fun_with_testing"
15
+ # gem "debugger"
17
16
  end
17
+
18
+ gem "csv"
19
+ gem 'fun_with_gems', '~> 0.0', ">= 0.0.7"
data/README.rdoc CHANGED
@@ -7,150 +7,191 @@ CSV Madness tries to remove what little pain is left from Ruby's CSV class. Loa
7
7
 
8
8
  == Why should I use it?
9
9
 
10
- I like brief code and I cannot lie.
10
+ I like brief code and I cannot lie.
11
11
 
12
12
 
13
13
  == Examples
14
14
 
15
15
  CsvMadness makes some assumptions about your CSV file. It does assume headers, for example.
16
16
 
17
- The simplest case is when your columns are nicely named. For example, if you have a csv file named <tt>~/data/people.csv</tt>:
17
+ The simplest case is when your columns are nicely named. For example, if you have a csv file named `~/data/people.csv`:
18
+
19
+ "id","fname","lname","age","born"
20
+ "1","Mary","Moore","27","1986-04-08 15:06:10"
21
+ "2","Bill","Paxton","39","1974-02-22"
22
+ "3","Charles","Darwin","72",""
23
+ "4","Chuck","Norris","57","1901-03-02"
18
24
 
19
- <code>
20
- "id","fname","lname","age","born"
21
- "1","Mary","Moore","27","1986-04-08 15:06:10"
22
- "2","Bill","Paxton","39","1974-02-22"
23
- "3","Charles","Darwin","72",""
24
- "4","Chuck","Norris","57","1901-03-02"
25
- </code>
26
25
 
27
26
  ... then you can write code like so:
28
27
 
29
- '''require 'csv_madness'
30
- sheet = CsvMadness.load( "~/data/people.csv" )
31
- sheet.columns # => [:id, :fname, :lname, :age, :born]
32
- sheet.records.map(&:id) # => ["1", "2", "3", "4"]
33
- sheet.set_column_type(:id, :float)
34
- sheet.records.map(&:id) # => [1.0, 2.0, 3.0, 4.0]
35
- sheet.alter_column(:id) do |id|
36
- id + rand() - 0.5
37
- end
28
+ require 'csv_madness'
29
+
30
+ sheet = CsvMadness.load( "~/data/people.csv" )
31
+ sheet.columns # => [:id, :fname, :lname, :age, :born]
32
+ sheet.records.map(&:id) # => ["1", "2", "3", "4"]
33
+ sheet.set_column_type(:id, :float)
34
+ sheet.records.map(&:id) # => [1.0, 2.0, 3.0, 4.0]
35
+ sheet.alter_column(:id) do |id|
36
+ id + rand() - 0.5
37
+ end
38
+
39
+ sheet.records.map(&:id) # => [0.7186, 2.30134, 2.90132, 4.30124] (your results may vary)
40
+ mary = sheet[0]
38
41
 
39
- sheet.records.map(&:id) # => [0.7186, 2.30134, 2.90132, 4.30124] (your results may vary)
40
- mary = sheet[0]
42
+ "#{mary.lname}, #{mary.fname} (#{mary.id})" # => "Moore, Mary (1)"
41
43
 
42
- "#{mary.lname}, #{mary.fname} (#{mary.id})" # => "Moore, Mary (1)"
43
- '''
44
44
 
45
45
  If you're not satisfied with your column names, you can send your own, in the column order. An index can also be provided, which will allow you to use <tt>.fetch()</tt> to find specific records quickly:
46
46
 
47
- '''require 'csv_madness'
48
- sheet = CsvMadness.load( "~/data/people.csv",
49
- columns: [:uid, :first_name, :last_name, :years_on_planet, :birthday],
50
- index: :uid )
47
+ require 'csv_madness'
48
+ sheet = CsvMadness.load( "~/data/people.csv",
49
+ columns: [:uid, :first_name, :last_name, :years_on_planet, :birthday],
50
+ index: :uid )
51
+
52
+ sheet.fetch("2").years_on_planet # => "39"
51
53
 
52
- sheet.fetch("2").years_on_planet # => "39"
53
- '''
54
54
 
55
55
  **Note:** you can provide multiple indexes as an array. However many columns you index, you'll run into trouble if the index isn't unique for each record. (that may change in the future)
56
56
 
57
57
 
58
58
  It's useful to clean up your files. Say you have:
59
59
 
60
- """"id","fname","lname","age"," born "
61
- "1 ","Mary ","Moore","27","1986-04-08 15:06:10"
62
- ""," Bill ","Paxton",," Feb. 22, 1974 "
63
- ,"Charles "," Darwin","72 ",
64
- "4","Chuck","Norris",," 2 March 1901 "
65
- """
60
+ "id","fname","lname","age"," born "
61
+ "1 ","Mary ","Moore","27","1986-04-08 15:06:10"
62
+ ""," Bill ","Paxton",," Feb. 22, 1974 "
63
+ "3","Charles "," Darwin","72 "
64
+ "4","Chuck","Norris",," 2 March 1901 "
65
+
66
66
 
67
67
  Ick. Missing IDs, inconsistent date formats, leading and trailing whitespace... We can fix this.
68
68
 
69
- """require 'csv_madness'
70
- sheet = CsvMadness.load( "~/data/people.csv" )
71
- sheet.alter_cells do |cell, record|
72
- (cell || "").strip
73
- end # removes leading and trailing whitespace, and turns nils into ""
74
-
75
- sheet.set_column_type(:id, :integer, nil) # the last argument provides a default for blank records.
76
-
77
- # assumes the missing ids can be filled in sequentially.
78
- # While .alter_column() does take a blank as a second argument,
79
- # that's not what we want here. If a blank is provided, your
80
- # code will never see the records with blank entries.
81
- sheet.alter_column(:id) do |id, record|
82
- @count ||= 1
83
- if id.nil?
84
- id = @count
85
- @count += 1
86
- else
87
- @count = id + 1
88
- end
69
+ require 'csv_madness'
70
+
71
+ sheet = CsvMadness.load( "~/data/people.csv" )
72
+
73
+ # remove leading and trailing whitespace, and turns nils into ""
74
+ sheet.alter_cells do |cell, record|
75
+ (cell || "").strip
76
+ end
77
+
78
+ # the last argument provides a default for blank records.
79
+ sheet.set_column_type(:id, :integer, nil)
80
+
81
+ # assumes the missing ids can be filled in sequentially.
82
+ # While .alter_column() does take a default (second argument),
83
+ # which will fill in the blank cells,
84
+ # that's not what we want here.
85
+ #
86
+ # If a blank is provided, your
87
+ # code will never see the records with blank entries.
88
+ sheet.alter_column(:id) do |id, record|
89
+ @count ||= 1
90
+ if id.nil?
91
+ id = @count
92
+ @count += 1
93
+ else
94
+ @count = id + 1
95
+ end
89
96
 
90
- id
91
- end
97
+ id
98
+ end
99
+
100
+ sheet.column(:id) # => [1, 2, 3, 4]
101
+
102
+ # Reformat a column of dates.
103
+ require 'time'
104
+ sheet.alter_column(:born) do |date_string|
105
+ begin
106
+ Time.parse( date_string ).strftime("%Y-%m-%d")
107
+ rescue ArgumentError
108
+ ""
109
+ end
110
+ end
111
+
112
+ sheet.column(:date) # => ["1986-04-08", "1974-02-22", "", "1901-03-02"]
113
+
114
+ # The same thing can be accomplished more simply by saying <tt>sheet.set_column_type(:date)</tt>.
115
+ # Even better, record.date is then a Time object
116
+
117
+ # Now calculate everyone's age (ignoring and overriding the existing data)
118
+ sheet.alter_column(:age) do |age, record|
119
+ if record.blank?(:born)
120
+ ""
121
+ else
122
+ ((Time.now - Time.parse(record.born)) / 365.25 / 24 / 60 / 60).to_i # not production-worthy code
123
+ end
124
+ end
125
+
126
+ # save the cleaned data for the next stage of your process
127
+ sheet.write_to_file( "~/data/people.clean.csv", force_quotes: true )
92
128
 
93
- sheet.records.map(&:id) # => [1, 2, 3, 4]
129
+ You could do something similar to clean and standardize phone numbers, detect and delete/complete invalid emails, etc.
94
130
 
95
- require 'time'
96
- sheet.alter_column(:born) do |date_string|
97
- begin
98
- Time.parse( date_string ).strftime("%Y-%m-%d")
99
- rescue ArgumentError
100
- ""
101
- end
102
- end
103
131
 
104
- sheet.records.map(&:date) # => ["1986-04-08", "1974-02-22", "", "1901-03-02"]
132
+ === Adding, removing, and renaming columns ===
105
133
 
106
- # The same thing can be accomplished more simply by saying <tt>sheet.set_column_type(:date)</tt>.
107
- # Even better, record.date is then a Time object
108
134
 
109
- # Now calculate everyone's age (ignoring and overriding the existing data)
110
- sheet.alter_column(:age) do |age, record|
111
- if record.blank?(:born)
112
- ""
113
- else
114
- ((Time.now - Time.parse(record.born)) / 365.25 / 24 / 60 / 60).to_i # not production-worthy code
115
- end
116
- end
135
+ # Add 72 years to the date born.
136
+ sheet.set_column_type( :born, :date ) # replace date strings with Time objects
117
137
 
118
- sheet.write_to_file( "~/data/people.clean.csv", force_quotes: true ) # save the cleaned data for the next stage of your process
119
- """
138
+ sheet.add_column( :expected_death_date ) do |date, record|
139
+ record.born + ( 72 * 365 * 24 * 60 * 60 )
140
+ end
120
141
 
121
- You could do something similar to clean and standardize phone numbers, detect and delete/complete invalid emails, etc.
142
+ puts sheet[0].expected_death_date # should be in 2058
122
143
 
144
+ # But that's just morbid, so we drop the column
145
+ sheet.drop_column( :expected_death_date )
123
146
 
124
- === Adding, removing, and renaming columns ===
147
+ # Or, if you think you need the information, but need to be a bit more euphemistic about it
148
+ sheet.rename_column( :expected_death_date, :expiration_date )
125
149
 
126
- # Add 72 years to the date born.
127
- sheet.set_column_type( :born, :date ) # replace date strings with Time objects
128
150
 
129
- sheet.add_column( :expected_death_date ) do |date, record|
130
- record.born + ( 72 * 365 * 24 * 60 * 60 )
131
- end
151
+ === Using columns ===
132
152
 
133
- puts sheet[0].expected_death_date # should be in 2058
134
153
 
135
- # But that's just morbid, so we drop the column
136
- sheet.drop_column( :expected_death_date )
137
154
 
138
- # Or, if you think you need the information, but need to be a bit more euphemistic about it
139
- sheet.rename_column( :expected_death_date, :expiration_date )
155
+ sheet.set_column_type( :id, :integer )
140
156
 
141
- === Using columns ===
142
157
 
143
- sheet.set_column_type( :id, :integer )
158
+ # Returns each record's id as an array of integers
159
+ sheet.column( :id ).max # ==> 4
144
160
 
145
161
 
146
- # Returns each record's id, as an array
147
- sheet.column( :id ).max # ==> 4
162
+ === Builder ===
148
163
 
164
+ You have an array of objects. You want to write them to a spreadsheet.
149
165
 
166
+ sb = CsvMadness::Builder.new do |sb|
167
+ sb.column( :id )
168
+ sb.column( :addressee, "addressee_custom" )
169
+ sb.column( :street, "primary_address.street_address" )
170
+ sb.column( :street2, "primary_address.supplemental_address_1" )
171
+ sb.column( :city, "primary_address.city" )
172
+ sb.column( :state_code, "primary_address.state_code" )
173
+ sb.column( :formatted_zip, "primary_address.formatted_zip" )
174
+ sb.column( :phone, "phones.first.phone" )
175
+ sb.column( :contact, "congregation_fieldset.congregation_leader" )
176
+ sb.column( :email, "emails.first.email" )
177
+ sb.column( :greeting ) do |contact|
178
+ if contact.business?
179
+ "To our friends at #{contact.organization_name},"
180
+ elsif contact.person?
181
+ "Dear #{ contact.title } #{ contact.last_name }"
182
+ end
183
+ end
184
+
185
+ end
150
186
 
187
+ sheet = sb.build( [address1, address2, address3...] )
188
+
189
+ outfile = FunWith::Files::FilePath.home.join( "Documents", "addresses", "address_records.csv" )
190
+ sheet.write_to_file( outfile )
151
191
 
192
+ === Documentation is incomplete ===
152
193
 
153
- There are lots of other features, but they'll take time to test and document.
194
+ There are other features, but they'll take time to test and document.
154
195
 
155
196
 
156
197
 
data/Rakefile CHANGED
@@ -1,70 +1,89 @@
1
1
  # encoding: utf-8
2
+ require 'fun_with_gems'
3
+ require_relative File.join( "lib", "csv_madness" )
4
+ self.extend( FunWith::Gems::Rakefile)
2
5
 
3
- require 'rubygems'
4
- require 'bundler'
6
+ rakefile_setup CsvMadness
5
7
 
6
- begin
7
- Bundler.setup(:default, :development)
8
- rescue Bundler::BundlerError => e
9
- $stderr.puts e.message
10
- $stderr.puts "Run `bundle install` to install missing gems"
11
- exit e.status_code
12
- end
13
-
14
- require 'rake'
15
-
16
- require 'jeweler'
8
+ gem_specification do |gem|
9
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
10
+ # dependencies defined in Gemfile
11
+ gem.name = "csv_madness"
12
+ gem.homepage = "http://github.com/darthschmoo/csv_madness"
13
+ gem.license = "MIT"
14
+ gem.summary = "CSV Madness turns your CSV rows into happycrazy objects."
15
+ gem.description = "CSV Madness removes what little pain is left from Ruby's CSV class. Load a CSV file, and get back an array of objects with customizable getter/setter methods."
16
+ gem.email = "keeputahweird@gmail.com"
17
+ gem.authors = ["Bryce Anderson"]
17
18
 
18
- Jeweler::Tasks.new do |gem|
19
- # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
20
- gem.name = "csv_madness"
21
- gem.homepage = "http://github.com/darthschmoo/csv_madness"
22
- gem.license = "MIT"
23
- gem.summary = %Q{CSV Madness turns your CSV rows into happycrazy objects.}
24
- gem.description = %Q{CSV Madness removes what little pain is left from Ruby's CSV class. Load a CSV file, and get back an array of objects with customizable getter/setter methods.}
25
- gem.email = "keeputahweird@gmail.com"
26
- gem.authors = ["Bryce Anderson"]
27
- # dependencies defined in Gemfile
28
- gem.files = [ "./lib/csv_madness/data_accessor_module.rb",
29
- "./lib/csv_madness/record.rb",
30
- "./lib/csv_madness/sheet.rb",
31
- "./lib/csv_madness.rb",
32
- "./Gemfile",
33
- "./VERSION",
34
- "./README.rdoc",
35
- "./Rakefile",
36
- "./CHANGELOG.markdown",
37
- "./test/csv/simple.csv",
38
- "./test/helper.rb",
39
- "./test/test_csv_madness.rb",
40
- "./test/test_sheet.rb" ]
19
+ # dependencies defined in Gemfile
20
+ gem.files = Dir.glob( File.join( ".", "lib", "**", "*.rb" ) ) +
21
+ Dir.glob( File.join( ".", "test", "**", "*" ) ) +
22
+ %w( Gemfile Rakefile LICENSE.txt README.rdoc VERSION CHANGELOG.markdown )
23
+ # csv_madness.gemspec )
41
24
  end
42
25
 
43
- Jeweler::RubygemsDotOrgTasks.new
26
+ setup_gem_boilerplate
44
27
 
45
- require 'rake/testtask'
46
- Rake::TestTask.new(:test) do |test|
47
- test.libs << 'lib' << 'test'
48
- test.pattern = 'test/**/test_*.rb'
49
- test.verbose = true
50
- end
51
-
52
- # require 'rcov/rcovtask'
53
- # Rcov::RcovTask.new do |test|
54
- # test.libs << 'test'
28
+ #
29
+ #
30
+ # require 'rubygems'
31
+ # require 'bundler'
32
+ #
33
+ # begin
34
+ # Bundler.setup(:default, :development)
35
+ # rescue Bundler::BundlerError => e
36
+ # $stderr.puts e.message
37
+ # $stderr.puts "Run `bundle install` to install missing gems"
38
+ # exit e.status_code
39
+ # end
40
+ #
41
+ # require 'rake'
42
+ #
43
+ # require 'jeweler'
44
+ #
45
+ # Jeweler::Tasks.new do |gem|
46
+ # # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
47
+ # gem.name = "csv_madness"
48
+ # gem.homepage = "http://github.com/darthschmoo/csv_madness"
49
+ # gem.license = "MIT"
50
+ # gem.summary = "CSV Madness turns your CSV rows into happycrazy objects."
51
+ # gem.description = "CSV Madness removes what little pain is left from Ruby's CSV class. Load a CSV file, and get back an array of objects with customizable getter/setter methods."
52
+ # gem.email = "keeputahweird@gmail.com"
53
+ # gem.authors = ["Bryce Anderson"]
54
+ #
55
+ # # dependencies defined in Gemfile
56
+ # gem.files = Dir.glob( File.join( ".", "lib", "**", "*.rb" ) ) +
57
+ # Dir.glob( File.join( ".", "test", "**", "*" ) ) +
58
+ # %w( Gemfile Rakefile LICENSE.txt README.rdoc VERSION CHANGELOG.markdown csv_madness.gemspec )
59
+ #
60
+ # end
61
+ #
62
+ # Jeweler::RubygemsDotOrgTasks.new
63
+ #
64
+ # require 'rake/testtask'
65
+ # Rake::TestTask.new(:test) do |test|
66
+ # test.libs << 'lib' << 'test'
55
67
  # test.pattern = 'test/**/test_*.rb'
56
68
  # test.verbose = true
57
- # test.rcov_opts << '--exclude "gems/*"'
58
69
  # end
59
-
60
- task :default => :test
61
-
62
- require 'rdoc/task'
63
- Rake::RDocTask.new do |rdoc|
64
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
65
-
66
- rdoc.rdoc_dir = 'rdoc'
67
- rdoc.title = "csv_madness #{version}"
68
- rdoc.rdoc_files.include('README*')
69
- rdoc.rdoc_files.include('lib/**/*.rb')
70
- end
70
+ #
71
+ # # require 'rcov/rcovtask'
72
+ # # Rcov::RcovTask.new do |test|
73
+ # # test.libs << 'test'
74
+ # # test.pattern = 'test/**/test_*.rb'
75
+ # # test.verbose = true
76
+ # # test.rcov_opts << '--exclude "gems/*"'
77
+ # # end
78
+ #
79
+ # task :default => :test
80
+ #
81
+ # require 'rdoc/task'
82
+ # Rake::RDocTask.new do |rdoc|
83
+ # version = File.exist?('VERSION') ? File.read('VERSION') : ""
84
+ #
85
+ # rdoc.rdoc_dir = 'rdoc'
86
+ # rdoc.title = "csv_madness #{version}"
87
+ # rdoc.rdoc_files.include('README*')
88
+ # rdoc.rdoc_files.include('lib/**/*.rb')
89
+ # end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.4
1
+ 0.0.9
@@ -0,0 +1,100 @@
1
+ module CsvMadness
2
+ class Builder
3
+ attr_accessor :label
4
+
5
+ def initialize( &block )
6
+ @columns = {}
7
+ @column_syms = []
8
+
9
+ @module = Module.new # for extending
10
+ self.extend( @module )
11
+ yield self if block_given?
12
+ end
13
+
14
+ def column( sym, method_path = nil, &block )
15
+ warn( "#{sym} already defined. Overwriting." ) if @column_syms.include?( sym )
16
+
17
+ @column_syms << sym
18
+ @columns[sym] = if block_given?
19
+ block
20
+ elsif method_path
21
+ method_path
22
+ else
23
+ Proc.new(&sym)
24
+ end
25
+ end
26
+
27
+ # Three :on_error values:
28
+ # :print => Put an error message in the cell instead of a value
29
+ # :raise => Raise the error, halting the process
30
+ # :ignore => Hand back an empty cell
31
+ #
32
+ # Although ideally it should be configurable by column...
33
+ def build( objects, opts = { :on_error => :print } )
34
+ spreadsheet = CsvMadness::Sheet.new( @column_syms )
35
+
36
+ for object in objects
37
+ STDOUT << "."
38
+ record = {}
39
+ for sym in @column_syms
40
+ record[sym] = build_cell( object, sym, opts )
41
+ end
42
+
43
+ spreadsheet.add_record( record ) # hash form
44
+ end
45
+
46
+ spreadsheet
47
+ end
48
+
49
+ def build_cell( object, sym, opts = { :on_error => :print } )
50
+ column = @columns[sym]
51
+
52
+ case column
53
+ when String
54
+ build_cell_by_pathstring( object, column, opts )
55
+ when Proc
56
+ build_cell_by_proc( object, column, opts )
57
+ else
58
+ "no idea what to do"
59
+ end
60
+ end
61
+
62
+ def def( method_name, &block )
63
+ @module.send( :define_method, method_name, &block )
64
+ end
65
+
66
+ protected
67
+ def build_cell_by_pathstring( object, str, opts )
68
+ handle_cell_build_error( :build_cell_by_pathstring, opts ) do
69
+ for method in str.split(".").map(&:to_sym)
70
+ object = object.send(method)
71
+ end
72
+
73
+ object
74
+ end
75
+ end
76
+
77
+ def build_cell_by_proc( object, proc, opts )
78
+ handle_cell_build_error( :build_cell_by_proc, opts ) do
79
+ proc.call(object)
80
+ end
81
+ end
82
+
83
+ def handle_cell_build_error( caller, opts, &block )
84
+ begin
85
+ yield
86
+ end
87
+ rescue Exception => e
88
+ case opts[:on_error]
89
+ when nil, :print
90
+ puts "error #{e.message} #{caller}" if opts[:verbose]
91
+ "ERROR: #{e.message} (#{caller}())"
92
+ when :raise
93
+ puts "Re-raisinge error #{e.message}. Set opts[:on_error] to :print or :ignore if you want Builder to continue on errors."
94
+ raise e
95
+ when :ignore
96
+ ""
97
+ end
98
+ end
99
+ end
100
+ end