sakovias
sakovias

Reputation: 1434

Ruby: Dynamically creating function call arguments list from an array

I'm creating a spreadsheet using the axlsx gem. I'd like to set fixed width to on all spreadsheet columns and I need to call the function

def column_widths(*widths)
  widths.each_with_index do |value, index|
    next if value == nil
    Axlsx::validate_unsigned_numeric(value) unless value == nil
    find_or_create_column_info(index).width = value
  end
end

defined in the Axlsx::Worksheet with an arbitrary number of column widths. E.g. `sheet.column_width(20, 20, ..., 20). My method call looks like

sheet.column_widths [20]*headers.length

and it result in the error

ActionView::Template::Error (Invalid Data [20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20] for Invalid column width. must be [Fixnum, Integer, Float].

How can I dynamically create a proper method call for the unknown number of columns?

Upvotes: 2

Views: 432

Answers (1)

MrYoshiji
MrYoshiji

Reputation: 54882

Your problem is that the method column_widths is defined like this:

def column_widths(*widths)
  # some stuff

The splatter operator * present in the arguments *widths means that you can have from 1 to N (where N > 1) arguments. You are trying to use this method with an array of Integer, instead you should pass each Integer as single argument, something like:

sheet.column_widths(20, 20, 20, 20, #etc...

But this is not the best way to do it. One better way to use these arguments is to also use the splatter operator:

sheet.column_widths(*[20]*headers.length)
                   #^ This is the splatter operator

A very explicit example of the utility of the splatter operator (in my IRB console, Ruby 1.9.3p489):

ann, marc, john = *['Ann', 'Marc', 'John']
# => ["Ann", "Marc", "John"] 
ann
# => "Ann"

Some stuff about the splatter operator: http://4loc.wordpress.com/2009/01/16/the-splat-operator-in-ruby/

Upvotes: 1

Related Questions