By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
437,809 Members | 1,999 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 437,809 IT Pros & Developers. It's quick & easy.

what is scope of $1 or why can't I call the same sub twice?

BeemerBiker
P: 87
This should have worked. It only printed 11111 and did not print the 22222. So am I missing a "delete $1" or a "free $1" before the routine returns? Googleing was not helpful.

Expand|Select|Wrap|Line Numbers
  1. use strict;
  2. use warnings;
  3.  
  4. sub printit {
  5.  my ($c) = @_;
  6.  
  7. print "arg:" . $c . "\n";
  8.  
  9.  $c=~ ?<nonce>(.*)</nonce>?;
  10.  
  11.  print "between the nonce: " . $1 . " \n";
  12.  
  13. }
  14.  
  15. my $a = "<nonce>11111</nonce>";
  16. my $b = "<nonce>22222</nonce>";
  17.  
  18. printit $a;
  19. printit $b;
=========results below=====
Expand|Select|Wrap|Line Numbers
  1. C:\perl>test99.pl
  2. arg:<nonce>11111</nonce>
  3. between the nonce: 11111
  4. arg:<nonce>22222</nonce>
  5. Use of uninitialized value $1 in concatenation (.) or string at C:\perl\test99.pl line 12.
  6. between the nonce:
  7.  
;
May 30 '10 #1

✓ answered by numberwhun

Ok, I did some playing with this one and here is my revised version of your script, which works as you expect:

Expand|Select|Wrap|Line Numbers
  1. #!/usr/bin/perl
  2.  
  3.     use strict;
  4.     use warnings;
  5.  
  6.     sub printit {
  7.          my ($c) = shift @_;
  8.  
  9.          print "arg:" . $c . "\n";
  10.  
  11.          $c =~ m/<nonce>(.*)<\/nonce>/;
  12.  
  13.          print "between the nonce: " . $1 . " \n";
  14.  
  15. }
  16.  
  17. my $a = "<nonce>11111</nonce>";
  18. my $b = "<nonce>22222</nonce>";
  19.  
  20. &printit($a);
  21. &printit($b);
  22.  
You will notice the regex right off and that I have changed it. First, you really shouldn't use characters for the opening and closing of the regex that have special meaning to a regex. The "?" are such characters. You could use something like & even, but not something reserved for regex's. Also, when you use a different character than the standard / to start and end a regex, you need to put the m before the regex to precede the change. Its common practice.

Another thing, inside the regex, you need to put a backslash before the forward slash, or it won't work either.

I also touched up your coding for neatness and my own anality.

Also, to answer your question... there is no way to clear the variables of the regex out other than to have the function/subroutine end. When it does, they clear naturally.

Regards,

Jeff

Share this Question
Share on Google+
3 Replies


numberwhun
Expert Mod 2.5K+
P: 3,503
Ok, I did some playing with this one and here is my revised version of your script, which works as you expect:

Expand|Select|Wrap|Line Numbers
  1. #!/usr/bin/perl
  2.  
  3.     use strict;
  4.     use warnings;
  5.  
  6.     sub printit {
  7.          my ($c) = shift @_;
  8.  
  9.          print "arg:" . $c . "\n";
  10.  
  11.          $c =~ m/<nonce>(.*)<\/nonce>/;
  12.  
  13.          print "between the nonce: " . $1 . " \n";
  14.  
  15. }
  16.  
  17. my $a = "<nonce>11111</nonce>";
  18. my $b = "<nonce>22222</nonce>";
  19.  
  20. &printit($a);
  21. &printit($b);
  22.  
You will notice the regex right off and that I have changed it. First, you really shouldn't use characters for the opening and closing of the regex that have special meaning to a regex. The "?" are such characters. You could use something like & even, but not something reserved for regex's. Also, when you use a different character than the standard / to start and end a regex, you need to put the m before the regex to precede the change. Its common practice.

Another thing, inside the regex, you need to put a backslash before the forward slash, or it won't work either.

I also touched up your coding for neatness and my own anality.

Also, to answer your question... there is no way to clear the variables of the regex out other than to have the function/subroutine end. When it does, they clear naturally.

Regards,

Jeff
May 31 '10 #2

BeemerBiker
P: 87
Thanks Jeff - I would not have spotted the problem with the regex, especially since it worked on the first call to the subroutine.

I also tried the following which got rid of the $1 but still had the same bad behavior:
Expand|Select|Wrap|Line Numbers
  1. my ($uno) = $c=~ ?<nonce>(.*)</nonce>?;
  2. print "between the nonce: " . $uno . " \n";
  3.  
I am thinking that the fact it worked on the first call but not the second is more likely a bug than a feature of ActivePerl 5.10.1.

The actual text I was trying to parse was quote
"<boinc_gui_rpc_reply>
<nonce>1275311433.448608</nonce>
</boinc_gui_rpc_reply>"

I thought I had to have the ? to match the extra stuff before and after the <nonce> newlines
May 31 '10 #3

numberwhun
Expert Mod 2.5K+
P: 3,503
Well, I am not using ActivePerl, I am using Perl itself as I am on Linux. Not sure why it works the first time through, but it does, and that seems to be just how it was evaluated. I would certainly avoid using regex characters as the regex begin/end characters. Use something safer. Some people prefer to use the % sign instead. Its up to you.

Regards,

Jeff
May 31 '10 #4

Post your reply

Sign in to post your reply or Sign up for a free account.