我正在尝试使用Highline gem进行Ruby密码输入,因为我有两次用户输入密码,所以我想消除我传入的块上的重复。例如,我现在正在做的简单版本是:
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
遗憾的是,这不起作用。这样做的正确方法是什么?
答案 0 :(得分:70)
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
答案 1 :(得分:13)
这是你应该如何做到的,简洁明了:
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)
答案 2 :(得分:4)
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)}
答案 3 :(得分:2)
这是一个示例,它将使用yield方法为索引添加前缀,并使用call方法附加索引。
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
答案 4 :(得分:-3)
我不认为该语言支持这样的结构。我能看到以任何方式概括这一点的唯一方法是:
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
,你只需要在一个代码中添加代码的地方。