Ruby中用于密码检查的递归循环



好的,我正在尝试写一个简单的对象,它将包含两个字符串,一个是"用户密码",一个为"目标密码",如果你想在远程服务器上使用sudo编写密码更改脚本,这将是必要的(第一个密码将执行sudo命令,"目标密码"将是密码应该重置的字符串。

我希望提示用户输入第一个密码一次,然后用户将有五次尝试输入第二个密码字符串并准确重复。下面的代码似乎不起作用。有什么想法吗?

require 'pp' 
require 'RubyGems'
require 'highline/import'  #gem install highline
class Authorization
attr_reader :user_password , :target_password
 pass_code = lambda {
 first_attempt = ask("Enter target password:  "){ |q| q.echo = '*' }
 second_attempt = ask("Re-enter password to verify"){ |q| q.echo = '*'}
}
 ### So we need some sort of recursive loop
def initialize(target_pass=false)
@user_password = ask("Enter your admin password:  ") { |q| q.echo = '*' }
if target_pass
  count = 1
  while n < 6
  pass_code
      if first_attempt == second_attempt
        @target_password =  first_attempt
        return
      else
        count += 1  
      end
    end
  end 
    end
  end
   my_pass = Authorization.new(true)
   pp "pass" , my_pass

我看到有几个问题

  • require "rubygems"(不是RubyGems)
  • 此外,如果使用Ruby1.9,则不需要加载rubygems
  • lambda分配了在构造函数中不可用的本地作用域变量
  • lambda定义本身无论如何都超出了访问范围
  • 循环永远不会终止(顺便说一句,这不是递归)

不如试试这样的。

require "highline/import"
class Authorization
  attr_accessor :user_password, :target_password
  def prompt(prompt_for_target = false)
    self.user_password = ask_for_password("Enter your admin password")
    return unless prompt_for_target
    5.times do
      password     = ask_for_password("Enter target password")
      confirmation = ask_for_password("Re-enter password to verify")
      if password == confirmation
        self.target_password = password
        return
      end
    end
  end
  private
  def ask_for_password(message)
    ask("#{message}: ") { |q| q.echo = '*' }
  end
end
auth = Authorization.new
auth.prompt(true)
puts auth.user_password
puts auth.target_password

非常简单,类似于Ryan的解决方案:

require 'highline/import'  #gem install highline
class Authorization
  attr_reader :admin_password, :target_password
  def initialize
    @admin_password = ask_for_password("Enter your admin password: ")
    5.times do
      @target_password = ask_for_password("Enter target password: ")
      verify_target_pass = ask_for_password("Re-enter password to verify: ")
      break if @target_password == verify_target_pass
      @target_password = nil
    end
  end 
  private
  def ask_for_password(message)
    ask(message) {|q| q.echo = "*"}
  end
end
my_pass = Authorization.new
puts "Administrator's password is: #{my_pass.admin_password}"
puts "Target password is: #{my_pass.target_password}"

首先,感谢大家的回答。这是我的第一个问题,不幸的是,结果有点混乱,但你们似乎都很理解。

IMHO,我想做的是递归,但我不确定这是否是讨论的最佳场所。

我使用的是Ruby 1.8.7,我可能应该在文章开头提到它。Ryan的解决方案奏效了,但只有当我去掉对"self"的引用并在实例变量中替换时:

@user_password = ask_for_password("Enter your admin password") #instead of
self.user_password = ask_for_password("Enter your admin password")  

对于Ruby 1.9来说,这可能不是必要的,但它确实有一个优点,那就是prostosper的与Ryan的几乎相同。

再次感谢大家!这是一次很棒的"湿脚"体验。

首先,这不是递归。这就是迭代。递归函数会再次调用自己:

def factorial(n)
    if (n == 0)
        1
    else
        n * factorial(n-1)
    end
end

现在,针对您遇到的具体问题;您正试图循环使用以下条件:

while n < 6

但请注意,在循环的主体中,您没有做任何更改n值的操作。所以你的循环不能终止。(此外,由于您一开始就忘记为n赋值,它可能也无法启动。:)

最新更新