Вернуть имя аргумента вместо его значения - Ruby - PullRequest
3 голосов
/ 14 апреля 2020

Мне нужно напечатать результат функции .max, но с отображением имени ее аргумента, а не его целевого значения (числа), используемого методом .max.

def who_is_bigger(a,b,c)
  "#{[a,b,c].max} is bigger"
end

Ожидаемый результат :

expect(who_is_bigger(84, 42, 21)).to eq("a is bigger")
expect(who_is_bigger(42, 84, 21)).to eq("b is bigger")
expect(who_is_bigger(42, 21, 84)).to eq("c is bigger")

Ответы [ 2 ]

3 голосов
/ 14 апреля 2020

Насколько я знаю, нет простого или понятного способа получить имя аргумента из его значения. (См. В нижней части ответа один из способов сделать это следующим образом.)

Вместо этого, вот способ, которым я бы это сделал, который я считаю приятным и читабельным:

def who_is_bigger(a,b,c)
  values = {a: a, b: b, c: c}
  largest_key, _ = values.max_by { |key, value| value }
  "#{largest_key} is bigger"
end

Это работает следующим образом:

  1. Построить ха sh из аргументов и сохранить его в values. Например, это га sh может быть { a: 84, b: 42, c: 21 }.
  2. Найти наибольшее значение в этом га sh, используя метод Enumerable#max_by. Это сохранит массив из 2 элементов в largest_pair, например, [:a, 84]. Обратите внимание, что ключ, который нам нужен, является первым элементом, поэтому мы используем деструктуризацию, чтобы извлечь первый элемент из этой пары и сохранить его в largest_key.

  3. . Построить строку и вернуть ее из метод.


Если вы хотите сделать это таким образом, чтобы вы динамически обращались к именам и значениям параметров и итерировали их, вы можете использовать это:

def who_is_bigger(a,b,c)
  params = method(__method__).parameters
  values = params.map { |_, name| [name, binding.local_variable_get(name)] }.to_h
  largest_key, _ = values.max_by { |key, value| value }
  "#{largest_key} is bigger"
end

Хотя, на мой взгляд, это выглядит немного странно и труднее для чтения, чем другое решение.

2 голосов
/ 14 апреля 2020

Вот еще один способ сделать это, используя Binding и max_by из Ruby:

def who_is_bigger(a, b, c)
  biggest = binding.local_variables.max_by do |v|
              binding.local_variable_get(v) || -Float::INFINITY
            end
  "#{biggest} is biggest"
end

who_is_bigger(10, 21, 30)
=> "c is biggest"

who_is_bigger(40, 31, 30)
=> "a is biggest"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...