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}"