user input behavior from within a subroutine
bw
created: 2006-08-02 11:15:01
Hello,
(I'm using ActiveState v. 5.6.1 Build 638)

When I use the /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 = ;
	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";
	}
}
Re: user input behavior from within a subroutine
created: 2006-08-02 11:34:53

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
Re^2: user input behavior from within a subroutine
created: 2006-08-02 14:10:44
Good point, it could be a cacheing issue. Adding $|=1; before the prompt might do the trick.

Update: Oops. Reading from STDIN flushes STDOUT.

Re^2: user input behavior from within a subroutine
bw
created: 2006-08-02 14:15:00
The code is:
if ($value_add gt 0){
	foreach $value (@value_add){
	print "Is $value an attribute (y or n)?  ";
	$response = ;
	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).
Re^3: user input behavior from within a subroutine
created: 2006-08-02 14:46:51

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','position','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 = ;
      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.

Re^2: user input behavior from within a subroutine
bw
created: 2006-08-08 13:02:51
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
created: 2006-08-02 11:52:54
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 = ;
      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";
      }
   }
}
Re^2: user input behavior from within a subroutine
bw
created: 2006-08-02 14:03:15
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
created: 2006-08-02 13:33:58
Do you unset $/ elsewhere in your program?
Re^2: user input behavior from within a subroutine
bw
created: 2006-08-02 13:59:55
No -- I don't do anything with $/ in the program.
Re: user input behavior from within a subroutine
created: 2006-08-02 16:03:49
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$..$/
Re^2: user input behavior from within a subroutine
bw
created: 2006-08-02 16:30:48
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.
Re^3: user input behavior from within a subroutine
created: 2006-08-02 17:26:27
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^4: user input behavior from within a subroutine
bw
created: 2006-08-03 09:51:44
I see in my earlier posting that I referred to the fully-qualified variable improperly. I should have said @main::whatever, not main::@whatever. I think that I understand that @main::whatever qualifies it, assuming I'm declaring the value in the 'main' part of the program and not in a subroutine somewhere, for the rest of the program.
If I use it within a subroutine (declaring it first in the 'main' portion of the program), am I correct to understand that I should pass it to the subroutine as subroutine_name(\@main::whatever)?

In any case, here's the answer to your question to me--

Doing:
use strict;
use warnings;

@existingattributes = ();
Produces the error:

Global symbol "@existingattributes" requires explicit package name at C:\Perl\scripts\configurator.pl line 5.
Execution of C:\Perl\scripts\configurator.pl aborted due to compilation errors.

But perl is happy when I do this:
use strict;
use warnings;

# initialize arrays
@main::existingattributes = ();
Re^5: user input behavior from within a subroutine
created: 2006-08-03 12:09:21
Hi [bw],

Very simply, because you need my in your declaration:

use strict;
use warnings;

my @existingattributes = ();

Then you will no longer get the error.

That's what use strict does; it enforces your declaration of variables with my or our.  Using [doc://my] lets you use it like a global variable (except that it's really a lexical variable), and it's visible only within the lexical scope in which it's declared.  If that's at the top of the program file, then the entire program can use it.

However, it you need to share variables between files, you may need to use [doc://our] instead.


s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
Re^6: user input behavior from within a subroutine
bw
created: 2006-08-03 12:50:47
> because you need my in your declaration
(insert sound of palm of right hand slapping my forehead here ...)

So simple that even I can understand it!

Thanks so much, liverpole

perlmonks.org content © perlmonks.org and bw, ikegami, liverpole, ptum, rodion

prlmnks.org © 2006 edmund von der burg (eccles & toad)

v 0.03