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. :)
精彩评论