开发者

Recursive loop for password checking in Ruby

OK, I am trying to write a simple object that will contain two strings, one a "user password" and one a "target password," this would be needed if you wanted to script a password change on a remote server using sudo (the first password would be to perform the sudo command, the "target password" would be the string to which the password should be reset.

I want the user to be prompted once for the first password, and then the user will have five tries to enter a second password string and repeat it accurately. What I came up with, the code below, does not seem to work. Any ideas?

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(t开发者_JS百科arget_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


I see several problems

  • It's require "rubygems" (not RubyGems)
  • Also, if using Ruby 1.9, loading rubygems isn't necessary.
  • The lambda has locally scoped variables assigned that aren't available in the constructor
  • The lambda definition itself is out of scope for access anyway
  • The loop never terminates (btw, this isn't recursion).

Try something like this instead.

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


Pretty straightforward and similar to Ryan's solution:

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


First, thank you all for your answers. This was my first question, and, unfortunately, came out a little garbled, but all of you seemed to understand it really well.

IMHO, what I was trying to do recursion, but I am not sure that this is the best place for that discussion.

I am using Ruby 1.8.7, which I probably should have mentioned at the beginning of the post. Ryan's solution worked, but only when I took out the references to "self" and substituted in the instance variable:

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

this might not be necessary for Ruby 1.9, but it does have the advantage of making prostosuper's almost identical to Ryan's.

Once again, thank you all! This has been a great "getting my feet wet" experience.


First, this isn't recursion. This is iteration. A recursive function would call itself again:

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

Now, for the specific problem you've got; you are trying to loop with the condition:

while n < 6

But note that in the body of your loop, you're doing nothing to change the value of n. So your loop cannot terminate. (Further, since you've forgotten to assign a value to n in the first place, it probably cannot start, either. :)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜