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

Hello,
(I'm using ActiveState v. 5.6.1 Build 638)

When I use the <STDIN>/chomp() snippet below within the listed subroutine, after entering the appropriate value the cursor goes to the beggining of the line. I must enter ctrl+z and then enter again to get the choice to 'take'.

The same type of code works just fine earlier in the script (the earlier code is not contained within a subroutine). What am I doing wrong here?
sub attrib_type { foreach $value (@attributes){ print "Is $value an attribute (y or n)? "; $response = <STDIN>; chomp($response); if ($response =~ "y" || $response =~ "Y"){ print "response is $response\n"; print "configure as an attribute\n"; } else { print "response is $response\n"; print "configure as a parser\n"; } }

Replies are listed 'Best First'.
Re: user input behavior from within a subroutine
by ptum (Priest) on Aug 02, 2006 at 15:34 UTC

    It looks to me as though you have a foreach {} loop that doesn't end properly (well, it is ended by what you seem to think, based on indentation, is the end of the subroutine). Maybe it is just a typo in your posted code ... ?

    It seems more likely (based on the code) that you would be repeatedly prompted for attribute value answers ... and since you're not printing a \n on the prompt line, it may look as though you're not really stepping through the attributes ... but still, I would think that your responses would be printed and would result in a carriage return/line feed ...

    Can you check your curly braces and make sure the code properly closes out the foreach loop, and post the actual output, please?


    No good deed goes unpunished. -- (attributed to) Oscar Wilde
      The code is:
      if ($value_add gt 0){ foreach $value (@value_add){ print "Is $value an attribute (y or n)? "; $response = <STDIN>; chomp($response); if ($response =~ "y" || $response =~ "Y"){ print "response is $response\n"; print "configure as an attribute\n"; } else { print "response is $response\n"; print "configure as a parser\n"; } } # end foreach $value (@value_add) }

      The @value_add array is:
      elevation location_type point_name position road type road type description vegetation
      (note: 'road type' and 'road type description' are separate elements).

        So, unless you declare $value up above this snippet, you aren't using strict, which is foolhardy. You seem to be using a string comparison operator (gt) for a numerical comparison, which doesn't seem the best way to skin this cat.

        In any case, the following standalone snippet works fine under perl 5.8.8 on a Solaris platform:

        #!/usr/local/bin/perl use strict; use warnings; Main: { my @param_names = ('elevation','location_type','point_name','positi +on','road_type','road_type_description','vegetation'); categorize_attributes(\@param_names); } sub categorize_attributes { my ($value_ref) = @_; my @value_add = (); @value_add = @{$value_ref} if ref($value_ref) eq 'ARRAY'; if (scalar(@value_add) > 0){ foreach my $value (@value_add){ print "Is $value an attribute (y or n)? "; my $response = <STDIN>; chomp($response); if ($response =~ /^y$/i){ print "response is $response\n"; print "configure as an attribute\n"; } else { print "response is $response\n"; print "configure as a parser\n"; } } # end foreach $value (@value_add) } }

        Update: Modified code sample so that the user input was handled by a subroutine, as specified by the OP.

      Good point, it could be a cacheing issue. Adding $|=1; before the prompt might do the trick.

      Update: Oops. Reading from STDIN flushes STDOUT.

      Thanks to ptum, rodion, ikegami, and liverpole for all your assistance. I found out that the source of my problem was a line that looked like:

      my @array=`cat path_to_target_file`;

      I changed that portion of the code to an open()/close() operation and the problem went away.
Re: user input behavior from within a subroutine
by rodion (Chaplain) on Aug 02, 2006 at 15:52 UTC
    With the brackets fixed I get the expected results in perl 5.8.7 and 5.6.1, with no need for a ctl-Z. Here's the test code I used, with the bracket corrected.
    my @attributes = qw(first second third); attrib_type(); sub attrib_type { foreach $value (@attributes){ print "Is $value an attribute (y or n)? "; $response = <STDIN>; chomp($response); if ($response =~ "y" || $response =~ "Y"){ print "response is $response\n"; print "configure as an attribute\n"; } else { print "response is $response\n"; print "configure as a parser\n"; } } }
      Yes, I've also been able to successfully reproduce your success with this code on my machine. By doing a straight cut-and-replace with your code, I still get my annoying behavior. I expect that I have a misplaced bracket elsewhere. So far nothing looks out of place.

      I hesitate to place the entire code as it is rather inelegant to say the least ...
Re: user input behavior from within a subroutine
by liverpole (Monsignor) on Aug 02, 2006 at 20:03 UTC
    Hi bw,

    What I would do (and often have done myself, either for a Perlmonks post, or just on my own), is to strip out parts of the code, a little bit at a time, and continuously retry it.  Your goal should be to make it as close to the original post as you can.  (And do, please, add "use strict;" and "use warnings;" at the top of the code first).

    If at any point it starts working, assuming the changes you made were small each time, you will probably say "Aha!", and have reached enlightenment on your own.

    If not, you can post the new, shortened, and hopefully less inelegant code here, and one of use will say "Aha!", and point you towards enlightenment.


    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
      Thank you liverpole. I will indeed take this approach. Regarding strict and warnings, I do use the latter. I've tried the former but don't understand it very well. As a result, I end up using it very badly.

      I'm having a tough time getting my mind around what 'use strict' does (though I'm busily poring through various FAQs I can find to sort it out). Any good/understandable-for-the-newbie links you happen to know on the subject will be most appreciated!

      As a "for instance" regarding my lack of 'strict', whenever I use an array where I've specified 'strict', I have to refer to it during the rest of the script as main::@whatever. I'm sure that's not the right way to approach this, but I haven't found a better way to do this.
        Hi again, bw,

            I have to refer to it during the rest of the script as main::@whatever

        No, you're correct that you shouldn't have to do that.  Can you post or /msg me a very short example?  I'll be happy to show you how to fix it.

        Here is the Perl documentation for use strict;.


        s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
Re: user input behavior from within a subroutine
by ikegami (Patriarch) on Aug 02, 2006 at 17:33 UTC
    Do you unset $/ elsewhere in your program?
      No -- I don't do anything with $/ in the program.