ellem has asked for the wisdom of the Perl Monks concerning the following question:

I was playing about with Learning Perl 3 when I tried to "improve" on an example. The example calls for an array to be reverse printed _but_ requires CTRL-D to signal the exit of the program.
I thought, "Bah I will assign 'q' as the signal to end the program! I have used it before."
But this time is different. This time I am not chomp(ing) the <STDIN> so the input is _never_ 'q'.
How would you fix this code?
#! /usr/local/bin/perl use warnings ; use strict ; #LP3 ex3-1 #Reverse a string my $q = 0 ; until ($q) { print "Enter some stuff. Hit 'q' to quit: " ; my @input = <STDIN> ; if (@input eq 'q') { $q = 1 ; } else { my @rev = reverse @input ; print @rev ; } }

--
ellem@optonline.net
There's more than one way to do it, just don't use my way.

Replies are listed 'Best First'.
Re: A quit key when no chomp
by Juerd (Abbot) on Mar 03, 2002 at 01:57 UTC
    The diamond operator (readline) slurps all of the contents when used in list context. When using standard input, the termination is (under *nix) ^D - End Of Transfer.
    You'll need to read in the items one by one:
    print "...\n" my @input; while (<STDIN>) { last if /^q$/; push @input, $_; } print reverse @input;

    I used the regex ^q$ so the trailing newline is optional (not possible when using console input, but it is possible when piping: cat script | perl reverse.pl).

    ++ vs lbh qrpbqrq guvf hfvat n ge va Crey :)
    Nabgure bar vs lbh qvq fb jvgubhg ernqvat n znahny svefg.
    -- vs lbh hfrq OFQ pnrfne ;)
        - Whreq
    

      Well it took 4 hours and a trip to several perldoc pages but I understand your answer. Far better than the clunky solution I was going for; thanks!
      --
      ellem@optonline.net
      There's more than one way to do it, just don't use my way.
        That's good :)

        It might seem a bit unreasonable to give an example implementation that differs a lot without adding step-by-step explanation. But this way, you're encouraged to read documentation. And I'm sure you learned a lot more than you wanted to :).

        ++ vs lbh qrpbqrq guvf hfvat n ge va Crey :)
        Nabgure bar vs lbh qvq fb jvgubhg ernqvat n znahny svefg.
        -- vs lbh hfrq OFQ pnrfne ;)
            - Whreq
        

Re: A quit key when no chomp
by erikharrison (Deacon) on Mar 03, 2002 at 06:38 UTC

    Since you're going to have to rewrite the code to step through each entry individually, telling you this isn't cheating.

    A common mistake for people learning Perl (even if they're experienced programmers) is to learn what those funny characters mean. You can't say:

    if (@input eq 'q') {

    - because the @ funny character indicates an array(see #1) .

    So @input indicates the whole array - making it nonsensical to ask if the array is equal to anything (see #2). If you want to ask if a particular element of an array is equal to anything, you have to refer to that element explicitly, using the $ funny character. So, to test the first element of an array, we do somthing like this:

    @foo = ('Bob', 'Tim', 'Bongo - The Jungle Avenger'); if ($foo[0] eq 'Bob') { #The $ indicates a single element #and [0] indicates which one print "Everything has gone as planned"; }


    Cheers,
    Erik

    #1 - Well, not exactly true. It indicates a list out of a data structure, so it could be an array or and array slice or a hash slice.

    #2 - Also not entirely true. The @input is in scalar context, so it does make sense to ask if it's equal to something . . .just not the sense we think it does.

      Ahh... that makes sense. How can the array eq one thing or another it is a list!
      Still I won't know what the input is. And the input won't be chomped for output reasons.
      So my first order of business is to get the array scalar(?) and find the 'q\n'?
      No wonder Randal didn't write it this way in the book!
      --
      ellem@optonline.net
      There's more than one way to do it, just don't use my way.

        A thing to keep in mind is what chomp really does. chomp is a safe chop. I don't want to give it away, but reconsider whether or not it matters if you chomp the input when you know what character will be removed.

        Cheers,
        Erik