user3185958
user3185958

Reputation: 87

Using index value in method

In my Rails application, in a model, I am trying to use the loop index x in the following method, and I can't figure out how to get the value:

def set_winners ## loops over 4 quarters
    1.upto(4) do |x|
        qtr_[x]_winner.winner = 1
        qtr_[x]_winner.save
    end
end

I'm going to keep searching but any help would be greatly appreciated!

edit: So I guess I can't do that! Here is the original method I was trying to refactor in full by looping four times:

def set_winners
       ## set all 4 quarter's winning squares
        home_qtr_1 = game.home_q1_score.to_s.split('').last.to_i
        away_qtr_1 = game.away_q1_score.to_s.split('').last.to_i
        qtr_1_winner = squares.where(xvalue:home_qtr_1, yvalue:away_qtr_1).first
        qtr_1_winner.winner = 1
        qtr_1_winner.save

        home_qtr_2 = game.home_q2_score.to_s.split('').last.to_i
        away_qtr_2 = game.away_q2_score.to_s.split('').last.to_i
        qtr_2_winner = squares.where(xvalue:home_qtr_2, yvalue:away_qtr_2).first
        qtr_2_winner.winner = 1
        qtr_2_winner.save

        home_qtr_3 = game.home_q3_score.to_s.split('').last.to_i
        away_qtr_3 = game.away_q3_score.to_s.split('').last.to_i
        qtr_3_winner = squares.where(xvalue:home_qtr_3, yvalue:away_qtr_3).first
        qtr_3_winner.winner = 1
        qtr_3_winner.save

        home_qtr_4 = game.home_q4_score.to_s.split('').last.to_i
        away_qtr_4 = game.away_q4_score.to_s.split('').last.to_i
        qtr_4_winner = squares.where(xvalue:home_qtr_4, yvalue:away_qtr_4).first
        qtr_4_winner.winner = 1
        qtr_4_winner.save
end

Is there a better way to do this if it's bad practice to dynamically change attribute names?

Upvotes: 0

Views: 80

Answers (2)

Intelekshual
Intelekshual

Reputation: 7566

Based on your edit, you don't need dynamic variables. The only thing that changes in your loop is game.home_qN_score, so that's what the focus of your refactoring should be. Given that, here's a viable solution:

1.upto(4) do |i|
    home_qtr = game.send("home_q#{i}_score)".to_s.split('').last.to_i
    away_qtr = game.send("away_q#{i}_score)".to_s.split('').last.to_i
    winner = squares.where(xvalue:home_qtr, yvalue:away_qtr).first
    winner.winner = 1
    winner.save
end

Original answer:

If qtr_1_winner, etc. are instance methods, you can use Object#send to achieve what you want:

def set_winners ## loops over 4 quarters
  1.upto(4) do |x|
    send("qtr_#{x}_winner").winner = 1
    send("qtr_#{x}_winner").save
  end
end

Upvotes: 0

the Tin Man
the Tin Man

Reputation: 160551

It looks like you are trying to do a PHP-like trick in a language that doesn't support it, and where we recommend NOT doing it because it results in code that is very difficult to debug due to the dynamically named variables.

It looks like you want to generate a variable name using:

qtr_[x]_winner

to create something like:

qtr_1_winner

Instead, consider creating an array named qtr_winner containing your objects and access the elements like:

qtr_winner[1]

or

qtr_winner[2]

etc.

You could create a hash to do a similar thing:

qtr_winner = {}
qtr_winner[1] = 5

then later access it using qtr_winner[1] and get 5 back or

qtr_winner[1].winner = 1

The determination of whether to use a hash or an array is whether you need to walk the container, or need random access. If you are always indexing into it using a value, then it's probably a wash about which is faster.

Upvotes: 1

Related Questions