2

EDIT: Someone pointed out that I needed to break correctly so I am editing the question

Scenario:
Please see following code:

print "UserID: "
uid = $stdin.gets.chomp
print "Password: "
pwd = $stdin.gets.chomp
usr_inp =  "#{uid};#{pwd}"
login_status = -1
# login_info.txt - "#{userid};#{password}" - format
File.open(File.join(File.dirname(__FILE__), 'login_info.txt'), "r") do |f|
    f.each_line do |line|
        puts line
        if (line.chomp == usr_inp)
            login_status = 1
        elsif (line.chomp != usr_inp && line.include?(uid)) #case a person inputs invalid password
            login_status = 0
        elsif (line.chomp != usr_inp && !(line.include?(uid))) #case a person inputs an invalid id
            login_status = 2
        end
    end
end
if (login_status == 1)
    puts "\nLogged in successfully: #{uid}"
elsif (login_status == 2)
    puts "\nSorry, that Employee does not exist."
elsif (login_status == 0)
    puts "\nLogin failed.\nPlease check credentials."
end

Problem:
break if (condition) exists in Ruby. But I don't waht that.
I want to do something like:

if (condition x)
    (do something)
    break
elsif (condition y)
    (do something else)
    break
else
    (whatever)
end

Maybe I am not understanding how ruby code works. Whenever I try to put the break as I want to use it, it associates with the next elsif.
Please help.

Spandan
  • 199
  • 1
  • 2
  • 8
  • 1
    You should break out of the loop if the correct user id and password are found, otherwise the next line will be checked and be incorrect. – Jonny Henly Sep 06 '16 at 17:34
  • @JonnyHenly: yes, there is this problem, I cannot break in ruby. There is a "break if (condition)" but that does not allow executing a block level statement like "login_status = 1". How to break and execute something at the same time? – Spandan Sep 06 '16 at 17:38
  • Can't you just use `break`, by itself? http://stackoverflow.com/questions/8502397/ruby-syntax-break-out-from-each-do-block – Jonny Henly Sep 06 '16 at 17:46
  • 2
    You certainly can break in Ruby. If you want `login_status` to be visible outside the block, you need to initialize it outside (before) the block. You don't need to "break and execute something at the same time." Execute something, then break. – Jordan Running Sep 06 '16 at 17:57
  • @Jordan: Exactly. Oh sorry `login_status` is already initialized outside in my original code at home. But as you mentioned. I need to execute something and break. Like `if (x), then do (y) break` - but I can't find that in ruby. – Spandan Sep 06 '16 at 18:01
  • @JonnyHenly - I don't want the `break if (condition)`. I want to execute something such that `if (condition), then do something, then break`. Doesn't Ruby have anything functionally equivalent to this syntax? – Spandan Sep 06 '16 at 18:09
  • 2
    Add `break` in a new line under the `login_saatus = 1` line. – Jonny Henly Sep 06 '16 at 18:14
  • `line.chomp!` once and then use `line`. There's no reason to `chomp` over and over and over and over again. – tadman Sep 06 '16 at 18:18
  • Instead of multiple `if (login_status == )` you could use `case login_status` and use `when`-statements, – knut Sep 06 '16 at 18:24
  • @knut @tadman - I am already incorporating all your suggestions into my original code, but please help me with the `break`. I can't understand why I can't break it like in **C** or **Java** – Spandan Sep 06 '16 at 18:27
  • 1
    @JonnyHenly has already explained the solution to your problem. You can do as many things as you want between `if` and `elsif`. Set `login_status` on one line and `break` on the next: `if condition1; do something; break; elsif condition2; do another thing; break; ...` (but with newlines instead of semicolons). – Jordan Running Sep 06 '16 at 18:32

1 Answers1

2

It depends on what you need and where you need it.

A script like this:

condition = 1
case condition
  when 1
    puts 'one'
    break
  when 2
    puts 'two'
  else
    puts 'Other %s' % condition
  end

puts 'end'

has a syntax error. break leaves a loop and there is no loop.

But with a loop, this works:

[1,2,3].each{|condition|
  case condition
    when 1
      puts 'one'
      break
    when 2
      puts 'two'
    else
      puts 'Other %s' % condition
    end
    puts 'end'
  }
  puts 'very end'

The output is:

one
very end

You see, the loop is stopped.

If you want to continue the loop with the next element, you need next (sorry, I'm just not aware what break is doing really in Java - it's been a long time since my last Java program):

[1,2,3].each{|condition|
  case condition
    when 1
      puts 'one'
      next
    when 2
      puts 'two'
    else
      puts 'Other %s' % condition
    end
    puts 'end %s' % condition
  }
  puts 'very end'

The result:

one
two
end 2
Other 3
end 3
very end

When you are not inside a loop (like in your code snippet), you may use exit (leave the program) or return (leave a method).

Jonny Henly
  • 4,023
  • 4
  • 26
  • 43
knut
  • 27,320
  • 6
  • 84
  • 112