2010-08-11 2 views
0

Возьмут следующий класс:Отражения от параметров методы в Ruby,

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) 

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

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

То, что я хочу, чтобы избежать это:

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

Duplicate of [Ruby - напечатать имя переменной, а затем ее значение] (http://stackoverflow.com/questions/2603617/ruby-print-the-variable-name-and-then-its-value) –

+0

Это является дубликатом [Есть ли способ вернуть имена параметров метода в ruby] (http://StackOverflow.Com/q/2452077/#2452322). –

ответ

3

Если вы не установили никаких других локальных переменных внутри метода, 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

Чисто зло не предназначено, а не то, что я хочу. Просто любопытно, есть ли способ сделать это. Я проверю ваши предложения и вернусь к вам –

+0

fields = {: first_name => first_name,: last_name => last_name} - это то, что я хочу. Спасибо. –

+0

Я попытался с Ruby 1.9.3, и вам нужно сделать # {eval var.to_s}, чтобы заставить его работать, иначе вы получите TypeError: не можете преобразовать символ в строку –

0

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

def fill_specific_form *args 
    #Process args 
end 
+0

Не совсем. Это получает только значения. Используя явные имена параметров, соответствующие имени элемента формы, я мог бы установить значение name =. См. Ответ sepp2k –

0

Отразить метод (или 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

Является ли это новым в 1.9.2? Это не работает для меня в 1.8.7 или 1.9.1. – sepp2k

+0

@ sepp2k: Да, 'ProC# parameters' является новым в 1.9.2. –

Смежные вопросы