Размышления о параметрах метода в Ruby - PullRequest
0 голосов
/ 11 августа 2010

Возьмите следующий класс:

class Automator
  def fill_specific_form(fields)
    fields.each_pair do |key, value|
      puts "Setting '#{key}' to '#{value}'"
    end
  end
end

a = Automator.new
a.fill_specific_form :first_name => "Mads", :last_name => "Mobæk"

# => Setting 'first_name' to 'Mads'
# => Setting 'last_name' to 'Mobæk'

Можно ли сделать то же самое без хеша?Поскольку все параметры обязательны, я хочу метод со следующей сигнатурой:

fill_specific_form(first_name, last_name)

На мой взгляд, это было бы возможно, если бы тело метода отражало и перебирало его параметры, таким образом достигая того же результата.1007 *

Как бы вы это реализовали?Шаблон / идиома для этого уже существует?Два очевидных преимущества - это информация о параметрах в IDE и отсутствие необходимости проверять, предоставлены ли все хеш-ключи.

Чего я хочу избежать, так это:

puts "Setting first_name to #{first_name}"
puts "Setting last_name to #{last_name}"
# and so on

Ответы [ 3 ]

3 голосов
/ 11 августа 2010

Если вы не устанавливаете другие локальные переменные внутри метода, local_variables выдаст вам список имен параметров метода (если вы установите другие переменные, вы можете просто вызвать local_variables и запомнить результат). Таким образом, вы можете делать то, что вы хотите с local_variables + eval:

class Automator
  def fill_specific_form(first_name, last_name)
    local_variables.each do |var|
      puts "Setting #{var} to #{eval var.to_s}"
    end
  end
end

Automator.new().fill_specific_form("Mads", "Mobaek")

Однако имейте в виду, что это чистое зло.

И хотя бы для вашего примера

puts "Setting first_name to #{first_name}"
puts "Setting last_name to #{last_name}"

кажется гораздо более разумным.

Вы также можете сделать fields = {:first_name => first_name, :last_name => last_name} в начале метода, а затем перейти с fields.each_pair кодом.

0 голосов
/ 11 августа 2010

Чтобы отразить параметры метода (или Proc), вы можете использовать Proc#parameters, Method#parameters или UnboundMethod#parameters:

->(m1, o1=nil, *s, m2, &b){}.parameters
# => [[:req, :m1], [:opt, :o1], [:rest, :s], [:req, :m2], [:block, :b]]

Однако в вашем случае я неНе понимаю, почему вам нужно отражение, так как вы уже знаете имена параметров в любом случае.

0 голосов
/ 11 августа 2010

Я не совсем понимаю. Вы хотите получить все параметры в одном массиве?

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