objetos manejo lista instanciar importar herencia funciones clases bloques ruby highline

manejo - Ruby: paso de bloques a métodos



manejo de clases en ruby (5)

Intento ingresar la contraseña de Ruby con la gema de Highline y dado que el usuario ingresó la contraseña dos veces, me gustaría eliminar la duplicación en los bloques que paso. Por ejemplo, una versión simple de lo que estoy haciendo en este momento es:

new_pass = ask("Enter your new password: ") { |prompt| prompt.echo = false } verify_pass = ask("Enter again to verify: ") { |prompt| prompt.echo = false }

Y a lo que me gustaría cambiarlo es algo como esto:

foo = Proc.new { |prompt| prompt.echo = false } new_pass = ask("Enter your new password: ") foo verify_pass = ask("Enter again to verify: ") foo

Lo cual desafortunadamente no funciona. ¿Cuál es la forma correcta de hacer esto?


No creo que el lenguaje soporte una construcción como esta. La única forma en que puedo ver para generalizar esto de alguna manera es:

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) }

En realidad, no acorta el código, aunque sí elimina algunas duplicaciones. Si quisiera hacer algo más que configurar prompt.echo en false , solo tendría que agregar el código en un lugar.


Así es como debes hacerlo, limpio y simple:

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)


Aquí hay un ejemplo que prefijará el índice con el método de rendimiento y anexará el índice con el método de llamada.

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


El código de David funcionará bien, pero esta es una solución más fácil y más corta:

foo = Proc.new { |prompt| prompt.echo = false } new_pass = ask("Enter your new password: ", &foo) verify_pass = ask("Enter again to verify: ", &foo)

También puede usar un signo de & para asignar un bloque a una variable al definir un método:

def ask(msg, &block) puts block.inspect end


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)}