Ruby - Передача блоков методам
Я пытаюсь выполнить ввод пароля Ruby с Highline gem, и поскольку у меня есть пароль пользователя дважды, я бы хотел для устранения дублирования на блоках, которые я передаю. Например, простая версия того, что я делаю прямо сейчас, это:
new_pass = ask("Enter your new password: ") { |prompt| prompt.echo = false }
verify_pass = ask("Enter again to verify: ") { |prompt| prompt.echo = false }
И что бы я хотел изменить, это примерно так:
foo = Proc.new { |prompt| prompt.echo = false }
new_pass = ask("Enter your new password: ") foo
verify_pass = ask("Enter again to verify: ") foo
К сожалению, это не работает. Каков правильный способ сделать это?
Ответы
Ответ 1
Код David будет работать нормально, но это более легкое и более короткое решение:
foo = Proc.new { |prompt| prompt.echo = false }
new_pass = ask("Enter your new password: ", &foo)
verify_pass = ask("Enter again to verify: ", &foo)
Вы также можете использовать амперсанд для назначения блока переменной при определении метода:
def ask(msg, &block)
puts block.inspect
end
Ответ 2
Вот как вы должны это делать, чистые и простые:
def ask(question)
yield(question)
end
proc = Proc.new { |question| puts question }
new_pass = ask("Enter your new password: ", &proc)
verify_pass = ask("Enter again to verify: ", &proc)
Ответ 3
foo = Proc.new { |prompt| prompt.echo = false }
new_pass = ask("Enter your new password: ") {|x| foo.call(x)}
verify_pass = ask("Enter again to verify: ") {|x| foo.call(x)}
Ответ 4
Вот пример, который будет префикс индекса с методом yield и добавит индекс с помощью метода вызова.
class Array
def alter_each!
self.each_with_index do |n, i|
self[i] = yield(n,i)
end
end
def modify_each!(add_one = true, &block)
self.each_with_index do |n, i|
j = (add_one) ? (i + 1) : i
self[i] = block.call(n,j)
end
end
end
a = ["dog", "cat", "cow"]
a.alter_each! do |n, i|
"#{i}_#{n}"
end
a.modify_each! false do |n,i|
"#{n}_#{i}"
end
puts a
Ответ 5
Я не думаю, что язык поддерживает такую конструкцию. Единственный способ, которым я могу это обобщить, - это:
def foo(prompt)
prompt.echo = false
end
new_pass = ask("Enter your new password: ") { |prompt| foo(prompt) }
verify_pass = ask("Enter again to verify: ") { |prompt| foo(prompt) }
Это действительно не сокращает код, хотя он удаляет некоторое дублирование - если вы хотите сделать больше, чем установить prompt.echo
на false
, вам нужно будет только добавить код в одном месте.