43

我正在尝试使用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

不幸的是,这不起作用。这样做的正确方法是什么?

4

5 回答 5

74

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
于 2008-11-11T18:04:05.633 回答
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)
于 2008-11-11T19:40:54.660 回答
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)}
于 2008-11-11T17:47:14.700 回答
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
于 2010-05-21T17:48:17.180 回答
-2

我不认为该语言支持这样的结构。我能看到以任何方式概括这一点的唯一方法是:

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

它并没有真正缩短代码,尽管它确实消除了一些重复——如果你想做的不仅仅是 set prompt.echoto false,你只需要在一个地方添加代码。

于 2008-11-11T17:46:06.950 回答