Gareth Burrows
Gareth Burrows

Reputation: 41

How do I get a string to behave as a variable?

In a controller I have an array which contains short versions of the months of the year:

@months = ['apr', 'may', 'jun', 'jul', 'aug', 'sep', 'aug', 'sep', 'oct', 'nov', 'dec', 'jan', 'feb', 'mar']

I then defined variables in the controller:

@apr_direct_income = 25300
@may_direct_income = 22100

and:

@april_partner_income = 1010
@may_partner_income = 2020

In the view I have to display all of these fields, and I can do it the long way, but was hoping to DRY it up a little by doing something like this in Haml:

- @months.each do |m|
  = "#{m}_direct_by_activation_date"

It will output the variables names correctly, but they are coming out as a string. I want it to realise it's a variable name and then go get the value from the controller, so instead of displaying:

@apr_direct_income
@may_direct_income

It displays:

25300
22100

I have about ten different types of income to display for each month, so if I can DRY this up in this manner it will turn hundreds of lines of repetitive code into a very small page.

Upvotes: 1

Views: 78

Answers (3)

Bala
Bala

Reputation: 11234

Consider this example:

@m = ["jan","feb"]
@jan_income = 1000
@feb_income = 500

eval "@"+@m[0]+"_income" #=> 1000

@m.each { |m| puts eval "@"+m+"_income" } => 1000, 500

Upvotes: 0

kalifs
kalifs

Reputation: 177

Do:

@months.each{|m| =instance_variable_get(:"@#{m}_direct_by_activation_date")

But, it would be better to use a Hash:

@direct_incomes = {"may" => 25300, "apr" => 22100}

#in view
@months.each do |m| 
   =@direct_incomes[m] 

Upvotes: 2

Dogbert
Dogbert

Reputation: 222040

You can get the value of an instance variable using instance_variable_get like this:

- @months.each do |m|
  = instance_variable_get("@#{m}_direct_income")

But you should look into using a Hash for this, and store the data in something like this:

@data = {
  april: {
    partner_income: 123,
    direct_income: 456
  }, may: {
    ...
  }
}

Then do:

- @data.each do |month, data|
  Month #{month}
  - data.each do |key, value|
    #{key} = #{value}

Upvotes: 5

Related Questions