Как использовать динамически созданную строку, которая соответствует локальной переменной в качестве этой переменной - PullRequest
0 голосов
/ 20 ноября 2019

У меня есть набор массивов:

metrics = ['value_one', 'value_two', 'value_three', 'value_four', 'value_five']

Затем я повторяю собранные оценки и суммирую значения каждой метрики:

survey_scores.each do |ss|
  if ss.survey.has_questions_for_metric?('value_one')
    value_one_count += 1
    value_one_score += ss.value_one_score
  end
  if ss.survey.has_questions_for_metric?('value_two')
    value_two_count += 1
    value_two_score += ss.value_two_score
  end
  if ss.survey.has_questions_for_metric?('value_three')
    value_three_count += 1
    value_three_score += ss.value_three_score
  end
  if ss.survey.has_questions_for_metric?('value_four')
    value_four_count += 1
    value_four_score += ss.value_four_score
  end
  if ss.survey.has_questions_for_metric?('value_five')
    value_five_count += 1
    value_five_score += ss.value_five_score
  end
end   

Я хочу получить эти значения, чтобы я могдобавьте к ним веса, и я хочу сделать это динамически, вместо того, чтобы писать пять if / else операторов, которые делают то же самое. Я использую:

metrics.each do |metric|
  if survey.has_questions_for_metric?(metric)
    puts "#{metric}_adjusted_score"
    "#{metric}_adjusted_score" = "#{metric}_score" / "#{metric}_count"
  end
end

, но это приводит к синтаксической ошибке

syntax error, unexpected '=', expecting keyword_end

, указывающей на знак равенства. Я предполагаю, что это читает их как строки, которые ничего не значат, но я не уверен. Если я вывожу в журнал, он показывает правильный текст переменной value_one_adjusted_score и т. Д., Но мне нужно, чтобы он был равен значению этой переменной, которое устанавливается, когда я прохожу все оценки.

У меня естьне нашел решение, которое позволило бы мне получить динамический доступ к переменным.

1 Ответ

3 голосов
/ 20 ноября 2019

Не делай этого. Вместо этого соберите хеш с помощью

scores =
  metrics.each_with_object({}) do |metric, acc|
    if survey.has_questions_for_metric?(metric)
      acc["#{metric}_adjusted_score"] = ...
    end
  end

Локальные переменные имеют множество ограничений, в том числе, но не ограничиваясь, областями видимости;с локальными переменными вам придется работать с binding, и код soo станет кошмаром для поддержки, даже несмотря на то, что это несколько возможно.


Оценка обновления блока может быть упрощена до:

survey_scores.
      each_with_object(Hash.new { |h, k| h[k] = {} }) do |ss|
  %w[value_one value_two value_three].each do |metric, acc|
    next unless ss.survey.has_questions_for_metric?(metric)

    acc[metric]["#{metric}_count"] += 1
    acc[metric]["#{metric}_score"] +=
      ss.public_send("#{metric}_score")
  end
end

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...