hirb 0.1.2
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.
- data/CHANGELOG.rdoc +9 -0
- data/LICENSE.txt +22 -0
- data/README.rdoc +231 -0
- data/Rakefile +49 -0
- data/VERSION.yml +4 -0
- data/lib/hirb.rb +31 -0
- data/lib/hirb/console.rb +17 -0
- data/lib/hirb/hash_struct.rb +17 -0
- data/lib/hirb/helpers.rb +7 -0
- data/lib/hirb/helpers/active_record_table.rb +17 -0
- data/lib/hirb/helpers/auto_table.rb +14 -0
- data/lib/hirb/helpers/object_table.rb +15 -0
- data/lib/hirb/helpers/parent_child_tree.rb +22 -0
- data/lib/hirb/helpers/table.rb +175 -0
- data/lib/hirb/helpers/tree.rb +177 -0
- data/lib/hirb/import_object.rb +10 -0
- data/lib/hirb/util.rb +29 -0
- data/lib/hirb/view.rb +201 -0
- data/lib/hirb/views/activerecord_base.rb +9 -0
- data/test/hirb_test.rb +23 -0
- data/test/import_test.rb +9 -0
- data/test/table_test.rb +263 -0
- data/test/test_helper.rb +17 -0
- data/test/tree_test.rb +167 -0
- data/test/util_test.rb +21 -0
- data/test/view_test.rb +169 -0
- metadata +83 -0
data/CHANGELOG.rdoc
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT LICENSE
|
2
|
+
|
3
|
+
Copyright (c) 2009 Gabriel Horner
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,231 @@
|
|
1
|
+
== Description
|
2
|
+
|
3
|
+
Hirb currently provides a mini view framework for console applications, designed with irb in mind.
|
4
|
+
Given the output of a console application, it renders a view if there is one configured, based on
|
5
|
+
the output's class. The framework encourages reusing views by letting you package them in classes
|
6
|
+
and associate them with any number of output classes. Hirb comes with tree views (see
|
7
|
+
Hirb::Helpers::Tree) and table views (see Hirb::Helpers::Table). By default Hirb displays Rails'
|
8
|
+
model classes as tables.
|
9
|
+
|
10
|
+
== Install
|
11
|
+
|
12
|
+
Install the gem with:
|
13
|
+
|
14
|
+
sudo gem install cldwalker-hirb --source http://gems.github.com
|
15
|
+
|
16
|
+
== Rails Example
|
17
|
+
|
18
|
+
Let's load and enable the view framework:
|
19
|
+
bash> script/console
|
20
|
+
Loading local environment (Rails 2.2.2)
|
21
|
+
irb>> require 'hirb'
|
22
|
+
=> true
|
23
|
+
irb>> Hirb::View.enable
|
24
|
+
=> nil
|
25
|
+
|
26
|
+
The default configuration provides table views for ActiveRecord::Base descendants.
|
27
|
+
If a class isn't configured, Hirb reverts to irb's default echo mode.
|
28
|
+
irb>> Hirb::View.output_config
|
29
|
+
=> {"ActiveRecord::Base"=>{:class=>"Hirb::Views::ActiveRecord_Base", :ancestor=>true}}
|
30
|
+
|
31
|
+
# Tag is a model class and descendant of ActiveRecord::Base
|
32
|
+
irb>> Tag.last
|
33
|
+
+-----+-------------------------+-------------+---------------+-----------+-----------+-------+
|
34
|
+
| id | created_at | description | name | namespace | predicate | value |
|
35
|
+
+-----+-------------------------+-------------+---------------+-----------+-----------+-------+
|
36
|
+
| 907 | 2009-03-06 21:10:41 UTC | | gem:tags=yaml | gem | tags | yaml |
|
37
|
+
+-----+-------------------------+-------------+---------------+-----------+-----------+-------+
|
38
|
+
1 row in set
|
39
|
+
|
40
|
+
irb>> 'plain ol irb'
|
41
|
+
=> 'plain ol irb'
|
42
|
+
irb>> :blah
|
43
|
+
=> :blah
|
44
|
+
|
45
|
+
From above you can see there were no views configured for a String or a Symbol so Hirb defaulted to
|
46
|
+
irb's echo mode. Also note that Tag was able to inherit its view from the ActiveRecord::Base config
|
47
|
+
because it had an :ancestor option.
|
48
|
+
|
49
|
+
Now that you understand that Hirb displays views based on an output object's class,
|
50
|
+
you may appreciate it also detects configured output objects in an array:
|
51
|
+
|
52
|
+
irb>> Tag.all :limit=>3, :order=>"id DESC"
|
53
|
+
+-----+-------------------------+-------------+-------------------+-----------+-----------+----------+
|
54
|
+
| id | created_at | description | name | namespace | predicate | value |
|
55
|
+
+-----+-------------------------+-------------+-------------------+-----------+-----------+----------+
|
56
|
+
| 907 | 2009-03-06 21:10:41 UTC | | gem:tags=yaml | gem | tags | yaml |
|
57
|
+
| 906 | 2009-03-06 08:47:04 UTC | | gem:tags=nomonkey | gem | tags | nomonkey |
|
58
|
+
| 905 | 2009-03-04 00:30:10 UTC | | article:tags=ruby | article | tags | ruby |
|
59
|
+
+-----+-------------------------+-------------+-------------------+-----------+-----------+----------+
|
60
|
+
3 rows in set
|
61
|
+
|
62
|
+
At any time you can disable Hirb if you really like irb's lovely echo mode:
|
63
|
+
irb>> Hirb::View.disable
|
64
|
+
=> nil
|
65
|
+
irb>> Tag.all :limit=>3, :order=>"id DESC"
|
66
|
+
=> [#<Tag id: 907, name: "gem:tags=yaml", description: nil, created_at: "2009-03-06 21:10:41",
|
67
|
+
namespace: "gem", predicate: "tags", value: "yaml">, #<Tag id: 906, name: "gem:tags=nomonkey",
|
68
|
+
description: nil, created_at: "2009-03-06 08:47:04", namespace: "gem", predicate: "tags", value:
|
69
|
+
"nomonkey">, #<Tag id: 905, name: "article:tags=ruby", description: nil, created_at: "2009-03-04
|
70
|
+
00:30:10", namespace: "article", predicate: "tags", value: "ruby">]
|
71
|
+
|
72
|
+
== Views: Anytime, Anywhere
|
73
|
+
While preconfigured tables are great for database records, sometimes you just want to create
|
74
|
+
tables/views for any output object:
|
75
|
+
|
76
|
+
#These examples don't need to have Hirb::View enabled.
|
77
|
+
irb>>Hirb::View.disable
|
78
|
+
=>nil
|
79
|
+
|
80
|
+
# Imports table() and view()
|
81
|
+
irb>>extend Hirb::Console
|
82
|
+
=>main
|
83
|
+
|
84
|
+
# Create a table of Dates comparing them with different formats.
|
85
|
+
irb>> table [Date.today, Date.today.next_month], :fields=>[:to_s, :ld, :ajd, :amjd, :asctime]
|
86
|
+
+------------+--------+-----------+-------+--------------------------+
|
87
|
+
| to_s | ld | ajd | amjd | asctime |
|
88
|
+
+------------+--------+-----------+-------+--------------------------+
|
89
|
+
| 2009-03-11 | 155742 | 4909803/2 | 54901 | Wed Mar 11 00:00:00 2009 |
|
90
|
+
| 2009-04-11 | 155773 | 4909865/2 | 54932 | Sat Apr 11 00:00:00 2009 |
|
91
|
+
+------------+--------+-----------+-------+--------------------------+
|
92
|
+
2 rows in set
|
93
|
+
|
94
|
+
# Same table as the previous method. However view() will be able to call any view created.
|
95
|
+
irb>> view [Date.today, Date.today.next_month], :class=>Hirb::Helpers::ObjectTable,
|
96
|
+
:fields=>[:to_s, :ld, :ajd, :amjd, :asctime]
|
97
|
+
|
98
|
+
If these console methods weren't convenient enough, try:
|
99
|
+
|
100
|
+
# Imports view() to all objects.
|
101
|
+
irb>> require 'hirb/import_object'
|
102
|
+
=>true
|
103
|
+
# Yields same table as above examples.
|
104
|
+
irb>> [Date.today, Date.today.next_month].view :class=>Hirb::Helpers::ObjectTable,
|
105
|
+
:fields=>[:to_s, :ld, :ajd, :amjd, :asctime]
|
106
|
+
|
107
|
+
Although views by default are printed to STDOUT, they can be easily modified to write anywhere:
|
108
|
+
# Setup views to write to file 'console.log'.
|
109
|
+
irb>> Hirb::View.render_method = lambda {|output| File.open("console.log", 'w') {|f| f.write(output) } }
|
110
|
+
|
111
|
+
# Writes to file with same table output as above example.
|
112
|
+
irb>> view [Date.today, Date.today.next_month], :class=>Hirb::Helpers::ObjectTable,
|
113
|
+
:fields=>[:to_s, :ld, :ajd, :amjd, :asctime]
|
114
|
+
|
115
|
+
# Doesn't write to file because Symbol isn't configured to use Hirb::View and thus defaults to irb's echo mode.
|
116
|
+
irb>> :blah
|
117
|
+
=>:blah
|
118
|
+
|
119
|
+
# Go back to printing Hirb views to STDOUT.
|
120
|
+
irb>> Hirb::View.reset_render_method
|
121
|
+
|
122
|
+
== Create and Configure Views
|
123
|
+
Let's create a simple view and configure it in different ways to be Hash's default view:
|
124
|
+
|
125
|
+
=== Setup
|
126
|
+
irb>> require 'hirb'
|
127
|
+
=>true
|
128
|
+
irb>> Hirb::View.enable
|
129
|
+
=>nil
|
130
|
+
irb>> require 'yaml'
|
131
|
+
=>true
|
132
|
+
|
133
|
+
=== Configure As View Method
|
134
|
+
A view method is the smallest reuseable view.
|
135
|
+
# Create yaml view method
|
136
|
+
irb>> def yaml(output); output.to_yaml; end
|
137
|
+
=>nil
|
138
|
+
|
139
|
+
# Configure view and reload it
|
140
|
+
irb>>Hirb::View.output_config = {"Hash"=>{:method=>:yaml}}
|
141
|
+
=>{"Hash"=>{:method=>:yaml}}
|
142
|
+
irb>>Hash::View.reload_config
|
143
|
+
=>true
|
144
|
+
|
145
|
+
# Hashes now appear as yaml
|
146
|
+
irb>>{:a=>1, :b=>{:c=>3}}
|
147
|
+
---
|
148
|
+
:a : 1
|
149
|
+
:b :
|
150
|
+
:c : 3
|
151
|
+
=> true
|
152
|
+
|
153
|
+
=== Configure As View Class
|
154
|
+
A view class is suited for more complex views. View classes can be under any namespace
|
155
|
+
and are expected to provide a render method. However, if a class is under the Hirb::Views namespace,
|
156
|
+
it will be automatically loaded with no configuration. Something to think about when
|
157
|
+
sharing views with others.
|
158
|
+
|
159
|
+
# Create yaml view class
|
160
|
+
irb>> class Hirb::Views::Hash; def self.render(output, options={}); output.to_yaml; end ;end
|
161
|
+
=>nil
|
162
|
+
# Just reload since no configuration is necessary
|
163
|
+
irb>>Hirb::View.reload_config
|
164
|
+
|
165
|
+
# Hashes now appear as yaml ...
|
166
|
+
|
167
|
+
Although the Hirb::Views namespace is great for quick classes that just plug and play, you
|
168
|
+
often want view classes that can be reused with multiple outputs. For this case, it's recommended to
|
169
|
+
use the Hirb::Helpers namespace.
|
170
|
+
|
171
|
+
# Create yaml view class
|
172
|
+
irb>> class Hirb::Helpers::Yaml; def self.render(output, options={}); output.to_yaml; end ;end
|
173
|
+
=>nil
|
174
|
+
|
175
|
+
# Configure view and reload it
|
176
|
+
irb>>Hirb::View.output_config = {"Hash"=>{:class=>"Hirb::Helpers::Yaml"}}
|
177
|
+
=>{"Hash"=>{:class=>"Hirb::Helpers::Yaml"}}
|
178
|
+
irb>>Hirb::View.reload_config
|
179
|
+
|
180
|
+
# Hashes now appear as yaml ...
|
181
|
+
|
182
|
+
=== Configure At Startup
|
183
|
+
Once you know what views are associated with what output classes, you can configure
|
184
|
+
them at startup by passing Hirb::View.enable a block:
|
185
|
+
# In .irbrc
|
186
|
+
require 'hirb'
|
187
|
+
# View class needs to come before enable()
|
188
|
+
class Hirb::Helpers::Yaml; def self.render(output, options={}); output.to_yaml; end ;end
|
189
|
+
Hirb::View.enable {|conf| conf.output = {"Hash"=>{:class=>"Hirb::Helpers::Yaml"}} }
|
190
|
+
|
191
|
+
Or by creating a config file at config/hirb.yml or ~/.hirb.yml:
|
192
|
+
# The config file for the yaml example would look like:
|
193
|
+
# ---
|
194
|
+
# :view :
|
195
|
+
# :output :
|
196
|
+
# Hash :
|
197
|
+
# :class : Hirb::Helpers::Yaml
|
198
|
+
|
199
|
+
# In .irbrc
|
200
|
+
require 'hirb'
|
201
|
+
# View class needs to come before enable()
|
202
|
+
class Hirb::Helpers::Yaml; def self.render(output, options={}); output.to_yaml; end ;end
|
203
|
+
Hirb::View.enable
|
204
|
+
|
205
|
+
== Contributing Views
|
206
|
+
If you have views of your own you'd like to share, fork Hirb and put your views under
|
207
|
+
the Hirb::Helpers namespace and the view files under lib/hirb/helpers/.
|
208
|
+
|
209
|
+
== Limitations
|
210
|
+
Although Hirb preserves Wirble colorizing irb's default echo mode, it doesn't colorize its own views.
|
211
|
+
This is mainly because colorizing caused table classes to render incorrectly. If you can get tables
|
212
|
+
and colors to work nicely, please fork. To colorize your Hirb output:
|
213
|
+
Hirb::View.render_method = lambda {|output| puts Wirble::Colorize.colorize(output) }
|
214
|
+
|
215
|
+
== Motivation
|
216
|
+
Table code from http://gist.github.com/72234 and {my console
|
217
|
+
app's needs}[http://github.com/cldwalker/tag-tree].
|
218
|
+
|
219
|
+
== Bugs
|
220
|
+
Please report them as tickets here: http://cldwalker.lighthouseapp.com/projects/27735-hirb/tickets
|
221
|
+
|
222
|
+
== Links
|
223
|
+
* http://tagaholic.me/2009/03/13/hirb-irb-on-the-good-stuff.html
|
224
|
+
* http://tagaholic.me/2009/03/18/ruby-class-trees-rails-plugin-trees-with-hirb.html
|
225
|
+
|
226
|
+
== Todo
|
227
|
+
* Configurable max height, which if exceeded activates a pager.
|
228
|
+
* Possibly add non-view irb goodies ie command manager.
|
229
|
+
* Consider applying multiple views/filters to output.
|
230
|
+
* Provides helper methods to all view classes.
|
231
|
+
* Consider adding a template system as needed.
|
data/Rakefile
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
begin
|
5
|
+
require 'rcov/rcovtask'
|
6
|
+
|
7
|
+
Rcov::RcovTask.new do |t|
|
8
|
+
t.libs << 'test'
|
9
|
+
t.test_files = FileList['test/**/*_test.rb']
|
10
|
+
t.rcov_opts = ["-T -x '/Library/Ruby/*'"]
|
11
|
+
t.verbose = true
|
12
|
+
end
|
13
|
+
rescue LoadError
|
14
|
+
puts "Rcov not available. Install it for rcov-related tasks with: sudo gem install rcov"
|
15
|
+
end
|
16
|
+
|
17
|
+
begin
|
18
|
+
require 'jeweler'
|
19
|
+
Jeweler::Tasks.new do |s|
|
20
|
+
s.name = "hirb"
|
21
|
+
s.description = "A mini view framework for console/irb that's easy to use, even while under its influence."
|
22
|
+
s.summary = s.description
|
23
|
+
s.email = "gabriel.horner@gmail.com"
|
24
|
+
s.homepage = "http://github.com/cldwalker/hirb"
|
25
|
+
s.authors = ["Gabriel Horner"]
|
26
|
+
s.has_rdoc = true
|
27
|
+
s.extra_rdoc_files = ["README.rdoc", "LICENSE.txt"]
|
28
|
+
s.files = FileList["[A-Z]*", "{bin,lib,test}/**/*"]
|
29
|
+
end
|
30
|
+
|
31
|
+
rescue LoadError
|
32
|
+
puts "Jeweler not available. Install it for jeweler-related tasks with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
33
|
+
end
|
34
|
+
|
35
|
+
Rake::TestTask.new do |t|
|
36
|
+
t.libs << 'lib'
|
37
|
+
t.pattern = 'test/**/*_test.rb'
|
38
|
+
t.verbose = false
|
39
|
+
end
|
40
|
+
|
41
|
+
Rake::RDocTask.new do |rdoc|
|
42
|
+
rdoc.rdoc_dir = 'rdoc'
|
43
|
+
rdoc.title = 'test'
|
44
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
45
|
+
rdoc.rdoc_files.include('README*')
|
46
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
47
|
+
end
|
48
|
+
|
49
|
+
task :default => :test
|
data/VERSION.yml
ADDED
data/lib/hirb.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
current_dir = File.dirname(__FILE__)
|
2
|
+
$:.unshift(current_dir) unless $:.include?(current_dir) || $:.include?(File.expand_path(current_dir))
|
3
|
+
require 'hirb/util'
|
4
|
+
require 'hirb/hash_struct'
|
5
|
+
require 'hirb/helpers'
|
6
|
+
require 'hirb/view'
|
7
|
+
require 'hirb/views/activerecord_base'
|
8
|
+
require 'hirb/console'
|
9
|
+
|
10
|
+
# Most of Hirb's functionality currently resides in Hirb::View.
|
11
|
+
# Hirb has an optional yaml config file defined by config_file. This config file
|
12
|
+
# has the following top level keys:
|
13
|
+
# [:view] See Hirb::View for the value of this entry.
|
14
|
+
module Hirb
|
15
|
+
class <<self
|
16
|
+
# Default is config/hirb.yml or ~/hirb.yml in that order.
|
17
|
+
def config_file
|
18
|
+
File.exists?('config/hirb.yml') ? 'config/hirb.yml' : File.expand_path(File.join("~",".hirb.yml"))
|
19
|
+
end
|
20
|
+
|
21
|
+
#:stopdoc:
|
22
|
+
def read_config_file(file=config_file)
|
23
|
+
File.exists?(file) ? YAML::load_file(file) : {}
|
24
|
+
end
|
25
|
+
|
26
|
+
def config(reload=false)
|
27
|
+
@config = (@config.nil? || reload) ? read_config_file : @config
|
28
|
+
end
|
29
|
+
#:startdoc:
|
30
|
+
end
|
31
|
+
end
|
data/lib/hirb/console.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
module Hirb
|
2
|
+
# This class is meant to be extended to provide methods for use in a console/irb shell.
|
3
|
+
# For example:
|
4
|
+
# irb>> extend Hirb::Console
|
5
|
+
# irb>> view 'some string', :class=>Some::String::Formatter
|
6
|
+
# irb>> table [[:row1], [:row2]]
|
7
|
+
module Console
|
8
|
+
# Renders a table for the given object. Takes same options as Hirb::Helpers::Table.render.
|
9
|
+
def table(output, options={})
|
10
|
+
Hirb::View.console_render_output(output, options.merge(:class=>"Hirb::Helpers::AutoTable"))
|
11
|
+
end
|
12
|
+
# Renders any specified view for the given object. Takes same options as Hirb::View.console_render_output.
|
13
|
+
def view(*args)
|
14
|
+
Hirb::View.console_render_output(*args)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/hirb/helpers.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
class Hirb::Helpers::ActiveRecordTable < Hirb::Helpers::ObjectTable
|
2
|
+
# Rows are Rails' ActiveRecord::Base objects.
|
3
|
+
# Takes same options as Hirb::Helpers::Table.render except as noted below.
|
4
|
+
#
|
5
|
+
# Options:
|
6
|
+
# :fields- Can be any attribute, column or not. If not given, this defaults to the database table's columns.
|
7
|
+
def self.render(rows, options={})
|
8
|
+
rows = [rows] unless rows.is_a?(Array)
|
9
|
+
options[:fields] ||=
|
10
|
+
begin
|
11
|
+
fields = rows.first.attribute_names
|
12
|
+
fields.unshift(fields.delete('id')) if fields.include?('id')
|
13
|
+
fields.map {|e| e.to_sym }
|
14
|
+
end
|
15
|
+
super(rows, options)
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Attempts to autodetect the table class the output represents and delegates rendering to it.
|
2
|
+
class Hirb::Helpers::AutoTable
|
3
|
+
# Same options as Hirb::Helpers::Table.render.
|
4
|
+
def self.render(output, options={})
|
5
|
+
klass = if ((output.is_a?(Array) && output[0].is_a?(ActiveRecord::Base)) or output.is_a?(ActiveRecord::Base) rescue false)
|
6
|
+
Hirb::Helpers::ActiveRecordTable
|
7
|
+
elsif options[:fields]
|
8
|
+
Hirb::Helpers::ObjectTable
|
9
|
+
else
|
10
|
+
Hirb::Helpers::Table
|
11
|
+
end
|
12
|
+
klass.render(output, options)
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class Hirb::Helpers::ObjectTable < Hirb::Helpers::Table
|
2
|
+
# Rows are any ruby objects. Takes same options as Hirb::Helpers::Table.render except as noted below.
|
3
|
+
#
|
4
|
+
# Options:
|
5
|
+
# :fields- Methods of the object which are represented as columns in the table. Required option.
|
6
|
+
# All method values are converted to strings via to_s.
|
7
|
+
def self.render(rows, options ={})
|
8
|
+
raise(ArgumentError, "Option 'fields' is required.") unless options[:fields]
|
9
|
+
rows = [rows] unless rows.is_a?(Array)
|
10
|
+
item_hashes = rows.inject([]) {|t,item|
|
11
|
+
t << options[:fields].inject({}) {|h,f| h[f] = item.send(f).to_s; h}
|
12
|
+
}
|
13
|
+
super(item_hashes, options)
|
14
|
+
end
|
15
|
+
end
|