Подтвердить что ты не робот

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

К сожалению, это не работает. Каков правильный способ сделать это?

4b9b3361

Ответ 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, вам нужно будет только добавить код в одном месте.