lib/csv_pirate.rb in csv_pirate-3.3.2 vs lib/csv_pirate.rb in csv_pirate-3.4.1
- old
+ new
@@ -45,10 +45,14 @@
attr_accessor :swab # default is :counter
attr_accessor :mop # default is :clean (only has an effect if :swab is :none) since overwriting is irrelevant for a new file
attr_accessor :swabbie # value of the counter / timestamp
attr_accessor :maroon # text of csv
attr_accessor :nocturnal # basename of the filepath (i.e. filename)
+ attr_accessor :blackjack # Hash: Specify how you want your CSV header
+ # {:join => '-'} joins the method names called to get hte data for that column with '_' underscores.
+ # {:humanize => '-'} first joins as above, then humanizes the string
+ # {:array => ['col1',col2','col3'] Uses the column names provided in the array. If the array provided is too short defaults to :humanize =>'_'
cattr_accessor :parlay # verbosity on a scale of 0 - 3 (0=:none, 1=:error, 2=:info, 3=:debug, 0 being no screen output, 1 is default
# CsvPirate only works for commissions of swag OR grub!
# :swag the ARrr collection of swag to work on (optional)
@@ -68,10 +72,14 @@
# :none - no iterative file naming convention, just use waggoner, aft and gibbet
# :mop can be :clean or :dirty (:overwrite or :append) (only has an effect if :swab is :none) since overwriting is irrelevant for a new file
# :clean - do not use :counter or :timestamp, and instead overwrite the file
# :dirty - do not use :counter, or :timestamp, or :overwrite. Just keep adding on.
# :bury_treasure should we store the csv data as it is collected in an array in Ruby form for later use (true), or just write the CSV (false)?
+ # :blackjack Specify how you want your CSV header
+ # {:join => '-'} joins the method names called to get hte data for that column with '_' underscores.
+ # {:humanize =>'-'} first joins as above, then humanizes the string
+ # {:array => ['col1',col2','col3'] Uses the column names provided. If the array provided is too short defaults to :humanize =>'_'
# See README for examples
def initialize(*args)
raise ArgumentError, "must provide required options" if args.blank?
@@ -111,10 +119,19 @@
@astrolabe = args.first[:astrolabe] || false
@bury_treasure = args.first[:astrolabe] || false
@buried_treasure = []
+ #Default is different than default for has_csv_pirate because this might gem wants to be clean for use outside rails, and humanize may not always be defined for String class
+ @blackjack = args.first[:blackjack] || {:join => '_'}
+
+ #Make sure the header array is the same length as the booty columns
+ if self.blackjack.keys.first == :array && (self.blackjack.values.first.length != self.booty.length)
+ @blackjack = {:join => '_'}
+ puts "Warning: :blackjack reset to {:join => '_'} because the length of the :booty is different than the length of the array provided to :blackjack" if CsvPirate.parlance(2)
+ end
+
# Initialize doesn't write anything to a CSV,
# but does create the traverse_board and opens the waggoner for reading / writing
self.northwest_passage unless self.astrolabe
# This will contain the text of the csv from this particular execution
@@ -142,10 +159,11 @@
:mop => args.first[:mop],
:grub => args.first[:grub],
:spyglasses => args.first[:spyglasses],
:booty => args.first[:booty],
:astrolabe => args.first[:astrolabe],
+ :blackjack => args.first[:blackjack],
:bury_treasure => args.first[:bury_treasure]
})
csv_pirate.hoist_mainstay()
csv_pirate
end
@@ -223,17 +241,60 @@
end
end
end
def sounding(csv)
- # create the header of the CSV (column/method names)
- csv << self.booty
+ csv << self.block_and_tackle
# create the data for the csv
self.dig_for_treasure do |treasure|
moidore = treasure.map {|x| "#{x}"}
csv << moidore # |x| marks the spot!
self.buried_treasure << moidore if self.bury_treasure
end
+ end
+
+ # create the header of the CSV (column/method names)
+ # returns an array of strings for CSV header based on blackjack
+ def block_and_tackle
+ self.blackjack.map do |k,v|
+ case k
+ #Joining is only relevant when the booty contains a nested hash of method calls as at least one of the booty array elements
+ #Use the booty (methods) as the column headers
+ when :join then self.binnacle(v, false)
+ #Use the humanized booty (methods) as the column headers
+ when :humanize then self.binnacle(v, true)
+ when :array then v
+ end
+ end.first
+ end
+
+ #returns an array of strings for CSV header based on booty
+ def binnacle(join_value, humanize = true)
+ self.booty.map do |compass|
+ string = compass.is_a?(Hash) ?
+ self.run_through(compass, join_value) :
+ compass.is_a?(String) ?
+ compass :
+ compass.is_a?(Symbol) ?
+ compass.to_s :
+ compass.to_s
+ humanize ? string.humanize : string
+ end
+ end
+
+ #Takes a potentially nested hash element of a booty array and turns it into a string for a column header
+ # hash = {:a => {:b => {:c => {:d => {"e" => "fghi"}}}}}
+ # run_through(hash, '_')
+ # => "a_b_c_d_e_fghi"
+ # Ooooh so recursive!
+ def run_through(hash, join_value)
+ hash.map do |k,v|
+ if v.is_a?(Hash)
+ [k,run_through(v, join_value)].join(join_value)
+ else #works for Symbols and Strings
+ [k,v].join(join_value)
+ end
+ end.first
end
#complete file path
def poop_deck
"#{self.analemma}#{self.swabbie}#{self.aft}"