“…dynamic (read: local) variables are also visible to functions called from within the block in which those variables are declared. Lexical (read: my) variables are not. They are totally hidden from the outside world including any called subroutines…”
I added the notes in parenthesis. Two test cases:
OUTPUT:#!c:\Apps\xampp\perl\bin\perl.exe -wT use strict; my $user_name; $user_name = $ARGV[0]; print "IN SCRIPT: user_name == $user_name\n"; login(); print "IN SCRIPT: user_name == $user_name\n"; sub login { print "IN SUBROUTINE: user_name == $user_name\n"; print "Can I change it in the subroutine?\n"; $user_name = "Bill"; print "IN SUBROUTINE: user_name == $user_name\n"; }
This program indicates I can access the variable’s value from a subroutine, and I can change it as well. How does that reconcile with the statements above from Programming Perl? Now the stumper, which is my web login script (greatly simplified here to illustrate only this problem):
OUTPUT (first run, user name supplied is Sam):use strict; my $user_name=""; $user_name = param('username'); print "Content-type: text/html\n\n"; print "<html><body><pre>\n"; print "IN SCRIPT: user_name == $user_name<br>\n"; login(); print "IN SCRIPT: user_name == $user_name\n"; print "</pre></body></html>\n"; sub login { print "IN SUBROUTINE: user_name == $user_name<br>"; print "Can I change it in the subroutine?<br>"; $user_name = "Bill"; print "IN SUBROUTINE: user_name == $user_name<br>\n"; }
IN SUBROUTINE: user_name == Sam
Can I change it in the subroutine?
IN SUBROUTINE: user_name == Bill
IN SCRIPT: user_name == Bill
OUTPUT (second run, user_name supplied is George):
IN SCRIPT: user_name == George
IN SUBROUTINE: user_name == Bill # <--Crazy!!
Can I change it in the subroutine?
IN SUBROUTINE: user_name == Bill
IN SCRIPT: user_name == George
Here’s the stumper part: When I call this the first time, the $user_name within the subroutine matches the $user_name in the main script and the one that was passed from the calling html form (the html form is at the bottom of this post for completeness). If I use the back button and enter a new user name, the master script has the new user name but the subroutine has the name from it’s prior run.
My questions:
Why, if variables declared private using my shouldn’t be available in a subroutine, are they available in a subroutine?
Why does my CGI script maintain information between executions?
Are there any other variable declarations I should know aside from my and local when using strict?
<html> <body><pre> <form method="post" action="projselect_test.pl"> <h2>System login</h2> User Name: <input type="text" name="username" size=15><br> Password: <input type="password" name="password" size=15><br> <input type="submit" value="Login"><p> </pre> </body> </html>
In reply to My, subroutines, scope, and CGI – Why can I see a private (my) variable in a subroutine but it doesn’t get updated? by Calm
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |