rept
rept

Reputation: 2246

Meta programming Ruby

I have this piece of code:

@timesheets.each do |ts|
  row = [
    ts.time_start.to_date,
    ts.time_start.to_time,
    ts.time_end.to_time,
    ts.task_link.project.client.name,
    ts.task_link.project.name,
    ts.task_link.task.name,
    ts.notes
  ]
  row.pop(3) if !@time_report.show_money
  sheet.add_row row, :style => [date_format, time_format, time_format, nil, nil, nil, nil, nil, nil, nil, nil, money_format, money_format, nil]
end

Now I want the user to be able to set the order him/herself. I would create a hash containing all the possible values (and also matching styles). But how do I integrate that into this procedure? I looked up some info about metaprogramming but that seems to be mostly with define_method. Is that the best option here?

Edit: I thought I had it because I could do:

Fields = [{'fieldname' => 'time_start', 'caption' => 'Date', 'type' => 'to_date', 'style' => 'date_format'},
{'fieldname' => 'time_start', 'caption' => 'Start', 'type' => 'to_time', 'style' => 'time_format'},
{'fieldname' => 'time_end', 'caption' => 'End', 'type' => 'to_time', 'style' => 'time_format'}]
...

And then be able to query like this:

@timesheets.each do |ts|
  row = []
  Fields.each do |f|
    row.append(ts[f].to_date)
  end
end

The 2 problems I'm having with this is:

How do I handle the 'ts.task_link.project.client.name' ?

ts[task_link.project.client.name] 

is a no-go.

Second problem: How can I integrate the to_date, to_time, etc... ?

Upvotes: 1

Views: 83

Answers (1)

A level of abstraction would make this much simpler. Create

RowEntry and Row

classes that encapsulate data format knowledge and simple ask each entry for it's display format. I don't really see any MetaProgramming required.

This line

sheet.add_row row, :style => [date_format, time_format, time_format, nil, nil, nil, nil, nil, nil, nil, nil, money_format, money_format, nil]

Becomes

sheet.add_row row.entries, row.style

More details:

RowEntry is essentially a struct that records both the value and the display style.

Row is an Array of RowEntry objects that knows how to extract both a plain Array of values and a plain Array of styles from the RowEntry Objects.

Upvotes: 1

Related Questions