0

I am trying to get something where if someone enters in a string, it verifies it and runs another function. My problem is that it ends the program instead of running the other function. Here is my code:

puts "redirecting to login"
def login()
  puts ""
  print "Username: "
  username = gets.chomp
  checkusername()
end
def password()
  print "Password: "
  passwordconf = gets.chomp
  checkpassword()
end
def success()
  puts "You're logged in!"
  loop { sleep 10 }
end
def checkusername()
if username == name
  password()
else
  login()
end
end
def checkpassword()
if passwordconf == password
  success()
else
  login()
end
end
login()
loop { sleep 10 }

When login is running, and I type the gets for the string I am trying to check, when I press enter for the checkusername to run, the program ends, even if it is correct.

The login function runs the checkusername function once I type in a string, and hit enter. My problem is that once that happens, the program terminates, instead of either redirecting back to the login function or the password function. I am trying to figure out how that will not happen.

Error output:

Traceback (most recent call last):
        2: from blank.rb:41:in `<main>'
        1: from blank.rb:16:in `login'
blank.rb:28:in `checkusername': undefined local variable or method `username' for main:Object (NameError)

I am quite a beginner at Ruby, and I have spent quite a bit of time getting this to work, but I am unable. Thanks!

Random Channel
  • 1,134
  • 9
  • 22

2 Answers2

2
puts 'redirecting to login'

def login
  puts  # You do not need the quotes just to put an empty line
  print 'Username: '
  username = gets.chomp
  check_username username  # I recommend using snake_case for variable names and method names
end

def password
  print 'Password: '
  password_conf = gets.chomp
  check_password password_conf
end

def success  # With Ruby you do not need the empty ()
  puts "You're logged in!"
end

def check_username(username)
  name = 'random'
  username == name ? password : login  # This is a if/else statement on one line
end

def check_password(password_conf)
  password = 'password'
  password_conf == password ? success : login  # You also don't need the () for calling a method either
end

login
loop { sleep 10 } # This will keep the program running forever, you should probably remove this line

I made some changes to your code, with some comments above.

Variables that are not global (You should avoid global variables) need to be passed to the method for use. This is the main reason your program is crashing. You are asking checkusername method to use a variable in the login method, which won't work as the methods won't share variables unless you pass them.

Again, I would avoid global variables when possible.

chemical
  • 380
  • 1
  • 10
0

You get the error message because username is unknown within the checkusername() function. It is said to be out of scope. It is not known outside of the login() function. It is a local variable. Its scope is local to login().

One way around this is to declare the variable as a global. That means it will have global scope and be available from anywhere in the program. To declare a variable as global, you prefix with a $.

username = gets.chomp becomes $username = gets.chomp. Then when you want to reference it again, you use the same prefix: if $username == name...

Difference between various variables scopes in ruby

http://ruby-for-beginners.rubymonstas.org/writing_methods/scopes.html

(Edit! As Sergio Tulentsev notes below, globals are usually a bad idea. https://www.thoughtco.com/global-variables-2908384)

user3574603
  • 2,805
  • 1
  • 21
  • 44