Forum: Ruby If statement

Posted by Masoud Ahmadi (ecsmaah)
on 2012-12-02 23:43
Will anyone be able to point out what I am doing wrong.
The code does not understand that I have said Q

    loop {
      puts("give me the command to execute or press Q to quit")
      op=gets
      if "#{op}" == "Q"
        then
        Kernel.exit(0)
      else
        value = `#{op}`
        puts "#{value}"
      end
    }
Posted by Bartosz Dziewoński (matmarex)
on 2012-12-03 00:10
(Received via mailing list)
The value returned by `gets` includes a trailing newline. Use
`gets.chomp` or `gets.strip` to remove it.

-- Matma Rex
Posted by Anna Vester (Guest)
on 2012-12-03 00:56
(Received via mailing list)
Masoud, I don't believe you need to interpolate the op, you can just use
op, for example:

if op == "Q"

Hope this helps,

Anna
Posted by 7stud -- (7stud)
on 2012-12-03 02:57
Masoud Ahmadi wrote in post #1087554:
> Will anyone be able to point out what I am doing wrong.
> The code does not understand that I have said Q
>
>     loop {
>       puts("give me the command to execute or press Q to quit")
>       op=gets
>       if "#{op}" == "Q"
>         then
>         Kernel.exit(0)
>       else
>         value = `#{op}`
>

You are also using backticks in the last line above, and backticks are
not the same as double quotes.

The gets() method always returns a string, and interpolating a string
into a string like you are doing accomplishes nothing--you can just use
the original string directly.  In
addition, assigning op to the variable value and then printing value
will give you the same result as printing op directly.



loop {
  puts("Enter the command to execute or press Q to quit: ")
  op = gets.chomp

  if ["Q", "q"].include?(op)
    Kernel.exit(0)
  else
    puts op
  end
}


How are you going to prevent someone from entering a command that erases 
your/their whole hard drive?
Posted by Joel Pearson (virtuoso)
on 2012-12-03 11:32
Are you sure this would work?

if ["Q", "q"].include?(op)

What about

if op.downcase == 'q'
Posted by Masoud Ahmadi (ecsmaah)
on 2012-12-03 12:35
This row solved my problem,
 if op == "Q\n"
I was not aware of this little new line thing

Cheers everyone
Posted by Ivan Cenov (jwalker)
on 2012-12-03 12:38
(Received via mailing list)
На 3.12.2012 г. 13:35 ч., Masoud Ahmadi написа:
> This row solved my problem,
>   if op == "Q\n"
> I was not aware of this little new line thing
>
> Cheers everyone
>
if ["Q\n", "q\n"].include?(op)

should work too...

--
Regards,

Ivan Cenov
OKTO-7 Co. Bulgaria
imc@okto7.com, i_cenov@botevgrad.com
mobile:+359888761080,
phone:+35972366161, fax:+_35972366262
Posted by Joel Pearson (virtuoso)
on 2012-12-03 12:39
If you do trust your user enough to let them execute system commands (I 
assume this is your goal with the backticks), I think the way to input a 
variable is this:

system("#{op}")
Posted by Robert Klemme (robert_k78)
on 2012-12-03 12:41
(Received via mailing list)
On Mon, Dec 3, 2012 at 12:35 PM, Masoud Ahmadi <lists@ruby-forum.com> 
wrote:
> This row solved my problem,
>  if op == "Q\n"
> I was not aware of this little new line thing

Just a note on that one: I think this solution is inferior to doing

op.chomp!
if op == "Q"

or

if op.chomp == "Q"

Reason: on other platforms you might get a different terminating
character than \n.  Also the terminator is usually not considered part
of the input.  You could even go a step further and get rid of
whitespace thus allowing for more valid inputs:

op = gets.strip

Kind regards

robert
Posted by Robert Klemme (robert_k78)
on 2012-12-03 12:42
(Received via mailing list)
On Mon, Dec 3, 2012 at 12:39 PM, Joel Pearson <lists@ruby-forum.com> 
wrote:
> If you do trust your user enough to let them execute system commands (I
> assume this is your goal with the backticks), I think the way to input a
> variable is this:
>
> system("#{op}")

Superfluous - this is sufficient:
system op

If you do not know whether op references a String you can do

system op.to_s

Kind regards

robert
Posted by tamouse mailing lists (Guest)
on 2012-12-04 04:21
(Received via mailing list)
On Sun, Dec 2, 2012 at 4:43 PM, Masoud Ahmadi <lists@ruby-forum.com> 
wrote:
>         value = `#{op}`
>         puts "#{value}"
>       end
>     }
>
> --
> Posted via http://www.ruby-forum.com/.

While others have addressed some of the syntax problems, I'd like to
address the overall approach.

In a "try something out, see how it works" approach, this is great.
But there are better ways to do something like this.

There are times when rolling a non-terminating loop with a mid-point
exit makes sense. However, there isn't much need to call the exit
method to do that.


loop do

break if condition

end

is the typical way to do this. This leaves your program a place to do
any sort of end clean up you might like to do, and so on. This sort of
thing is nice in the scenario you've devised at it most cleanly limits
the prompt, setting of the variable and test for completion once each
inside the loop, unlike while and unless will in this case.

If you'll permit, and this is in no way meant to say you're wrong in
your approach, just an offer, this is how I'd approach such a thing:

loop do
  puts("give me the command to execute or enter Q to quit")
  op = gets.strip   # the reason for strip was given above
  break if op == 'Q'
  value = system op ## HOLY KRAKEN ARE YOU SURE YOU WANT TO DO THIS???
  puts value
end

The point here is that calling the Kernel.exit(0) method makes the
code look a lot more complex that it is. Reserve the use of exit for
times when you want your code to exit early and report an error
(non-zero exit status) and then only if you've gotten yourself into a
place you don't really want to unwind, or it's just more clear to the
code reader what should be done. (Kinda like you should never end a
sentence with a preposition, but that is something with which one
aught not put up.) (Apologies, Churchill witicism.)

The other thing I'd like to point at is the if modifier -- these are
really nice little features in ruby (other languages have them, too)
that make the above very clean, to my eye. (Others will disagree, of
course.) But as you have this construction:

>       if "#{op}" == "Q"
>         then
>         Kernel.exit(0)
>       else
>         value = `#{op}`
>         puts "#{value}"
>       end

I just want to point out that the "then" is not needed at all, nor is
the else. Calling exit at that point *exits* the program immediately
-- there is no else possible. Shortening what you have a bit:

if op == "Q"
  Kernel.exit(0)
end

value = ... (and the rest)

is sufficient; Placing it in an else clause is overkill (and could
actually cause someone to overlook something if they were maintaining
such a construction).

Joel mentioned the issue of trusting users *not* to do something
malicious with thi (this DOES include yourself! -- mistakes do
happen). Something learn very early is never to trust user (or any)
input. I assume this is just a practice piece, which is fine.

Given the nature of this snippet, I'm assuming you are a beginning
programming? This is great! I hope you take my response in the manner
intended: encouraging, showing a little beyond the basic question "why
doesn't it work". Keep at it!
Posted by tamouse mailing lists (Guest)
on 2012-12-04 04:25
(Received via mailing list)
On Mon, Dec 3, 2012 at 9:21 PM, tamouse mailing lists
<tamouse.lists@gmail.com> wrote:

> if op == "Q"
>   Kernel.exit(0)
> end

Oh, crikey. This:

if op == "Q"
  break
end

See? Anyone can get confused :)
Posted by Matthew Kerwin (mattyk)
on 2012-12-04 04:32
(Received via mailing list)
On 4 December 2012 13:21, tamouse mailing lists 
<tamouse.lists@gmail.com>wrote:

> (Kinda like you should never end a
>
sentence with a preposition, but that is something with which one
>
aught not put up.) (Apologies, Churchill witicism.)
>

I believe you mean ". . . that is something up with which one ought not
put."

--
  Matthew Kerwin, B.Sc (CompSci) (Hons)
  http://matthew.kerwin.net.au/
  ABN: 59-013-727-651

  "You'll never find a programming language that frees
  you from the burden of clarifying your ideas." - xkcd
Posted by tamouse mailing lists (Guest)
on 2012-12-04 04:43
(Received via mailing list)
On Mon, Dec 3, 2012 at 9:30 PM, Matthew Kerwin <matthew@kerwin.net.au> 
wrote:
> I believe you mean ". . . that is something up with which one ought not
> put."

no doubt. :) That was how i actually wrote it, then thought, "no
that's not it.."
Posted by Masoud Ahmadi (ecsmaah)
on 2012-12-04 09:07
Thank you guys
As you may have understood, I have recently started learning Ruby, I am 
grateful for the advise you have given me

Cheers
Masoud
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.