Re: Getting a / when regex should produce nothing
Moin André, Am 26.04.2010 um 21:44 schrieb André Warnier: cr...@animalhead.com wrote: The retention of values from previous executions applies only to global variables. Ah, yes. But that would have triggered another discussion (which it might now still do of course), about what exactly /is/ a global variable, in the context of a mod_perl handler or perl script run under modperl::Registry. Let's first clarify it for Perl in general, and then for mod_perl. A global variable in Perl is any variable not declared with my. Which includes variables declared with our or use vars (I'll get to these), and also variables created by full qualification, as in $Bla::Blub = 1. A lexical variable in Perl is any variable declared with my, regardless of the scope, which may be file-level. Unlike globals, lexical variables aren't directly accessible from outside the package. A global variable declared (or introduced, or admitted) with use vars is in scope for the entire package where it is declared. A global variable declared with our is in scope only for the lexical scope where it is declared (see perldoc -f our). (There's also local, a misnomer, to temporarily stash away the current value of a global variable and shadow it with another value. We can leave it out of the picture here.) Now, how is this different for mod_perl? Well, it isn't, if you think about it, or rather it boils down to the difference between a mod_perl handler and your typical batch script. Your batch script is invoked, it runs, and ends. Running it probably includes some initialization code of yours placed at the file level. Next time around, the whole thing start anew. Nothing special here. A mod_perl handler, as you know, is loaded once, and unless it is reloaded, is only acted upon by invocation of its functions, such as handler(). Which means that reinitialization doesn't happen automatically, as with your batch script running in a new process each time. So what does this mean for file level lexical variables (my-variables) you have defined? Well, they don't get reinitialized (unless you provide code to do so), so they start behaving like global variables, retaining state between invocations. They are not, however, accessible from outside the current package, so they're still lexical variables. There's one more thing to understand, especially in the context of Apache::Registry and Apache2::Registry, and that's lexical my variables referenced from nested names subroutines. You do not usually create nested named subroutines, but the Registry handler does it for you by wrapping your registry script in a handler subroutine in a package made up from the filesystem path of rour registry script. So if you define a registry script with a subroutine that references a lexical variable from the enclosing scope, you'll see the familiar warning message Variable $x will not stay shared. You can read up about this issue here: http://perl.apache.org/docs/general/perl_reference/perl_reference.html Hope this helps :-) -- Michael.Ludwig (#) XING.com
Re: Getting a / when regex should produce nothing
On Tuesday 27 April 2010 10:18:17 Michael Ludwig wrote: A lexical variable in Perl is any variable declared with my, regardless of the scope, which may be file-level. Unlike globals, lexical variables aren't directly accessible from outside the package. Not quite correct. Consider this: $ perl -Mstrict -le ' my $x=10; our $y=20; { package hugo; print x=$x; # references $x outside of package hugo print y=$y; # references $main::y ($x,$y)=(1,2); } print x=$x; print y=$y ' x=10 y=20 x=1 y=2 $x is file-level lexical. It is visible all over the file. The embedded package hugo has no influence. Lexical variables are not bound to a package but to a lexical scope. Same with our-variables. Cour declares the visibility of a variable in the current lexical scope. You can read up about this issue here: http://perl.apache.org/docs/general/perl_reference/perl_reference.html Or for German speakers, there was a series of articles about scoping in $foo- magazin: http://foo-magazin.de/ Torsten Förtsch -- Need professional modperl support? Hire me! (http://foertsch.name) Like fantasy? http://kabatinte.net
Re: Getting a / when regex should produce nothing
Michael Ludwig wrote: Moin André, Am 26.04.2010 um 21:44 schrieb André Warnier: cr...@animalhead.com wrote: The retention of values from previous executions applies only to global variables. Ah, yes. But that would have triggered another discussion (which it might now still do of course), about what exactly /is/ a global variable, in the context of a mod_perl handler or perl script run under modperl::Registry. Let's first clarify it for Perl in general, and then for mod_perl. A global variable in Perl is any variable not declared with my. Which includes variables declared with our or use vars (I'll get to these), and also variables created by full qualification, as in $Bla::Blub = 1. A lexical variable in Perl is any variable declared with my, regardless of the scope, which may be file-level. Unlike globals, lexical variables aren't directly accessible from outside the package. A global variable declared (or introduced, or admitted) with use vars is in scope for the entire package where it is declared. A global variable declared with our is in scope only for the lexical scope where it is declared (see perldoc -f our). (There's also local, a misnomer, to temporarily stash away the current value of a global variable and shadow it with another value. We can leave it out of the picture here.) Now, how is this different for mod_perl? Well, it isn't, if you think about it, or rather it boils down to the difference between a mod_perl handler and your typical batch script. Your batch script is invoked, it runs, and ends. Running it probably includes some initialization code of yours placed at the file level. Next time around, the whole thing start anew. Nothing special here. A mod_perl handler, as you know, is loaded once, and unless it is reloaded, is only acted upon by invocation of its functions, such as handler(). Which means that reinitialization doesn't happen automatically, as with your batch script running in a new process each time. So what does this mean for file level lexical variables (my-variables) you have defined? Well, they don't get reinitialized (unless you provide code to do so), so they start behaving like global variables, retaining state between invocations. They are not, however, accessible from outside the current package, so they're still lexical variables. There's one more thing to understand, especially in the context of Apache::Registry and Apache2::Registry, and that's lexical my variables referenced from nested names subroutines. You do not usually create nested named subroutines, but the Registry handler does it for you by wrapping your registry script in a handler subroutine in a package made up from the filesystem path of rour registry script. So if you define a registry script with a subroutine that references a lexical variable from the enclosing scope, you'll see the familiar warning message Variable $x will not stay shared. You can read up about this issue here: http://perl.apache.org/docs/general/perl_reference/perl_reference.html Hope this helps :-) Very nice. And it does help my understanding. Although the key paragraph here, I would say, is : So what does this mean for file level lexical variables (my-variables) you have defined? Well, they don't get reinitialized (unless you provide code to do so), so they start behaving like global variables, retaining state between invocations. They are not, however, accessible from outside the current package, so they're still lexical variables. Let me give an example of how I understand this, for mod_perl handler packages : # -- start of code -- package My::Something; my $lexical_mine; sub access { my $r = shift; if (defined($lexical_mine) { $r-log_error(in access: value present : $lexical_mine); $lexical_mine++; } else { $lexical_mine = 1; $r-log_error(in access: initialised to : $lexical_mine); } return OK; } sub response { my $r = shift; if (defined($lexical_mine) { $r-log_error(in response: value present : $lexical_mine); $lexical_mine++; } else { $lexical_mine = 1; $r-log_error(in response: initialised to : $lexical_mine); } # .. generate some response for the browser return OK; } sub finalise { my $r = shift; my $lexical_mine; if (defined($lexical_mine) { $r-log_error(in finalise: value present : $lexical_mine); $lexical_mine++; } else { $lexical_mine = 1; $r-log_error(in finalise: initialised to : $lexical_mine); } return OK; } # -- end of code -- Now if I configure the first of these subs as a PerlAccessHandler and the second as a PerlResponseHandler, what happens to $lexical_mine ? It might be lexical, in the sense that there is no way for code in another file, to access this variable from outside as, for example, $My::Something::lexical_mine But for all intents and purposes, this variable is functionally global, in the sense that throughout the life of the Apache child that contains this perl interpreter, this variable is shared, not only
Re: Getting a / when regex should produce nothing
On Tue, Apr 27, 2010 at 7:16 AM, André Warnier a...@ice-sa.com wrote: Now if I configure the first of these subs as a PerlAccessHandler and the second as a PerlResponseHandler, what happens to $lexical_mine ? This is actually import to point out: it makes no difference if you configure these subs as mod_perl anything. There is no difference at all in scoping rules for mod_perl because mod_perl is just the perl interpreter running inside apache. The thing that can make it appear different is the lifecycle of the interpreter, i.e. the fact that it doesn't exit as soon as your code has run once. This doesn't change anything about scoping rules in perl though. But for all intents and purposes, this variable is functionally global, in the sense that throughout the life of the Apache child that contains this perl interpreter, this variable is shared, not only by the separate handler subs, but even by subsequent invocations of these subs in the course of processing all HTTP requests which happen to be processed by this Apache child.(*) I think it's better to say the variable is persistent rather than global, and the reason for that is that you're creating a closure. Again, not a mod_perl thing. Any time you reference a lexical variable from outside the sub you're in, it causes a closure. On the other hand, if I configure finalise as a PerlSomethingHandler, then the $lexical_mine that is defined inside it, does not play along with the other one. It is its own thing, and it will print its own incremental sequence 1,1,2,3,4,5 But it is still global in a sense : while private to the sub finalise, it nevertheless is shared between consecutive invocations of the same finalise() sub by the same Apache child. No, this isn't true. It's not a closure, so it will be undefined every time you enter the sub. It will also give you a warning about reusing the name of a lexical from a larger scope. So, back to the basics, my interpretation : by default, consider any variable as global/shared and you'll generally stay out of trouble. Here's another rule you could use: don't reference lexical variables defined outside of a sub from within that sub. Either use globals for things you want shared, or pass in the data you need as parameters. Then you won't be surprised by closures messing up your ideas about scoping. I also suggest that anyone who finds this confusing should have a look through the information on variable scoping in the perl man pages, Programming Perl, or perlmonks.org. It really pays to understand this stuff. - Perrin
Re: Getting a / when regex should produce nothing
On Apr 27, 2010, at 4:16 AM, André Warnier wrote: So, back to the basics, my interpretation : by default, consider any variable as global/shared and you'll generally stay out of trouble. Isn't it true that a variable declared (with my) inside of a sub (including a handler) starts its existence initialized for each execution of the sub? So I consider variables declared outside of any sub global and get along OK without knowing what lexical scope means, though I may have to learn someday. That is all I was trying to say in the post that triggered this thread's recent display of technical erudition. (*) which is going to be very confusing in the logfile however, as for now there is no way to distinguish which child logs a message. For that, we might want to add ($$) to the log messages. The 3rd field of Apache log file entries is quite useless, and I have long used it to include the process ID and keepalive status. Here's my log file format from httpd.conf: LogFormat %h %l %P:%{Connection}i%{Connection}o %t \%r\ %s %b \% {Referer}i\ \%{User-Agent}i\ keepalive Best Regards, cmac
Re: Getting a / when regex should produce nothing
Torsten Förtsch schrieb am 27.04.2010 um 11:25:33 (+0200): On Tuesday 27 April 2010 10:18:17 Michael Ludwig wrote: A lexical variable in Perl is any variable declared with my, regardless of the scope, which may be file-level. Unlike globals, lexical variables aren't directly accessible from outside the package. Not quite correct. Consider this: $ perl -Mstrict -le ' my $x=10; our $y=20; { package hugo; print x=$x; # references $x outside of package hugo print y=$y; # references $main::y Thanks for catching this. Indeed, lexical variables aren't described in terms of packages, but in terms of lexical scope. $x is file-level lexical. It is visible all over the file. The embedded package hugo has no influence. Lexical variables are not bound to a package but to a lexical scope. Same with our-variables. Cour declares the visibility of a variable in the current lexical scope. Variables declared with our are a funny hybrid between global variables, which are attached to a package, and lexical variables, which are attached to a scope. -- Michael Ludwig
Re: Getting a / when regex should produce nothing
On Tue, Apr 27, 2010 at 2:08 PM, Michael Ludwig mil...@gmx.de wrote: Variables declared with our are a funny hybrid between global variables, which are attached to a package, and lexical variables, which are attached to a scope. They are package variables (usually referred to as globals), which have a lexically-scoped alias that lets you call them by their short name. It's the short name alias that is lexical. Here's a normal use of a package variable: package Foo; use strict; use warnings; $Foo::bar = 1; sub print_it { print $Foo::bar; } And here's the exact same thing, using our to save some typing: package Foo; use strict; use warnings; our $bar; $bar = 1; sub print_it { print $bar; } Aside from the difference in how you refer to the variable, these are identical. Hope that helps. If it doesn't, try this: http://perldoc.perl.org/functions/our.html - Perrin
Re: Getting a / when regex should produce nothing
Perrin Harkins schrieb am 27.04.2010 um 14:20:13 (-0400): On Tue, Apr 27, 2010 at 2:08 PM, Michael Ludwig mil...@gmx.de wrote: Variables declared with our are a funny hybrid between global variables, which are attached to a package, and lexical variables, which are attached to a scope. They are package variables (usually referred to as globals), which have a lexically-scoped alias that lets you call them by their short name. It's the short name alias that is lexical. I used to think (and still do so) that non-lexical variables, just like subroutines, belong to the package they're in and do not need the package prefix. Using which, however, it is possible to refer to variables in a package other than the current one, like $Data::Dumper::Indent = 1 or something similar. But simply writing $bar in package Foo just refers to $Foo::bar: \,,,/ (o o) --oOOo-(_)-oOOo-- package Foo; $bar = 1; package main; print bar = $bar; print Foo::bar = $Foo::bar; - $ perl -l /tmp/pkg.pl bar = Foo::bar = 1 It's only the strict pragma that (fortunately) forces you to qualify your globals. In other words, the alias is not really an alias, but rather the thing itself, regardless of whether is is excepted from the strict 'vars' pragma by means of (1) full qualification or (2) use vars or (3) our. Here's a normal use of a package variable: package Foo; use strict; use warnings; $Foo::bar = 1; I think I've more frequently encountered the form: use strict; # ban unqualified globals use vars qw($bar); # make exceptions $bar = 1; # use them As perldoc -f our informs you, the above has been superseded by our. However, you still see a lot of use vars for reasons of backward compatibility. -- Michael Ludwig
Re: Getting a / when regex should produce nothing
I started learning mod_perl versus regular perl for web applications for two reasons. Mod_perl is much faster, but that was only an interest, not quite strong enough to push the effort, despite seeing many applications that are horribly slow without it. When someone said that using mod_perl was an easy way to deal with having apache chrooted without having to drag all kinds of files inside, that made my decision. I have not regretted it. I have learned many details that I could have overlooked with regular perl. Mod_perl is more unforgiving of not knowing exactly what my variables are doing and what values they hold This particular issue has taught me two things. I am never going to use no warnings 'uninitialized' again. It is too dangerous to be overlooking possible problems. It has also taught me that perl itself may leave values in variables such as $1, even after a server stop and start and first running of a program. Sounds like an early lesson out of C. Never assume anything is in fact defined without defining it yourself. Nope, not a perl guru, yet. But if you keep on thorough pointing out my every error clearly, I guess that will happen sooner! :) Thanks Chris Bennett
Re: Getting a / when regex should produce nothing
Chris Bennett wrote: ... I have not regretted it. I have learned many details that I could have overlooked with regular perl. Mod_perl is more unforgiving of not knowing exactly what my variables are doing and what values they hold Perl and nod_perl are very deterministic, and there is no mystery in what they do with variables. The trick is to understand exactly how mod_perl works, and how this plays along with the way Apache (in its different MPM variations) works. This particular issue has taught me two things. I am never going to use no warnings 'uninitialized' again. It is too dangerous to be overlooking possible problems. I agree. Maybe even do as Michael said, and make all warnings fatal, if we are talking about user/web oriented applications. It has also taught me that perl itself may leave values in variables such as $1, even after a server stop and start and first running of a program. That however, is definitely not the case. If you stop and start the server, you have a totally new environment, and there is nothing left from the previous one. If you are using a prefork version of the Apache server, then that is also true each time an Apache child ends and a new one is started : it gets a new perl and a new set of variables. (but the thing is, you mostly cannot predict when Apache will start a new child, nor which child will handle which request). For other Apache configurations, the situation may be a bit more complicated. The main aspect to understand with mod_perl (as opposed to running a perl program without it) : - when you run a perl script without mod_perl, the sequence is : - a new perl interpreter is started, clean - your script gets compiled, and gets a brand-new set of variables - your script gets run, starting with this new set of variables - your script exits - perl exits, and returns all its memory to the OS .. and the next time you run your script, the same steps happen. under mod_perl : - an Apache child starts, and it gets a new perl - your script gets compiled, the first time around. That time, it gets a brand-new set of variables. - your script gets run, the first time, with these brand-new variables. - when the script terminates, whatever is in these variables stays there. - the perl interpreter inside that same Apache child stays alive, amd it remembers the compiled code of your script. Now is the difference : when a new request comes into Apache, and (as may happen) it is sent to the *same* Apache child, it is processed by the same perl interpreter. And that one is not clean : it remembers your compiled script, and the state of its variables from the last execution. And that is where it starts from. The big gain is that perl does not have to compile the script again, it can run the compiled code right away. The big danger is that your variables start with the state in which the previous run of the same script in the same Apache child left them. That can sometimes be put to good use, but it is also deadly if you are not very careful. The above is only a very approximative explanation, and the reality is somewhat subtler. But if you stick to that basic explanation, you will avoid much trouble. The fact that your $1 variable retained a value from an earlier comparison however has nothing to do with the above. That would be true even if your script was not running under mod_perl. Sounds like an early lesson out of C. Never assume anything is in fact defined without defining it yourself. That is a good principle in general (and not only in perl). A final observation : at the beginning, I think what most perl/web programmers find the most interesting aspect of mod_perl is that scripts/modules run much faster (because they do not need to be re-compiled each time). But I find that the real benefit is more in terms of how closely it is integrated into the Apache insides, and the incredible power it gives you to create handlers and filters to let you intervene at just about every stage of the processing of a request, and use all the power and flexibility of perl (and of the CPAN library) to do all kinds of stuff you could not even dream of otherwise. reading the on-line mod_perl documentation is also a unique way to learn how Apache itself works.
Re: Getting a / when regex should produce nothing
André Warnier schrieb am 26.04.2010 um 10:22:18 (+0200): $article_file = $q-param(articlefilename); $article_file = $q-param(articlefilename) || ''; does not add much technically True, but no benefit either, other than telling the reader that the empty string is your default value, which would have also been Perl's default value. It could also be something differing from the Perl default: $article_file = $q-param(articlefilename) || get_dflt_article_name; But it makes *explicit* what you are doing, which makes the difference to someone maybe not as fluent in perl and who has to look at that code in a year's time. Okay, that's right. On the other hand, PHP works just like Perl without explicit 'uninitialized' warnings, and I guess this PHP trait is mostly thought of as a feature. (Which it is.) It is on the other hand perfectly ok in my view for a perl guru to write perl modules using whatever clever techniques and idioms suit him, as long as the module does what it claims to do. And as long as (preferably) any section of such code comes with ample internal documentation explaining what it does and what it relies on. I think that's the important part: document the intent. -- Michael Ludwig
Re: Getting a / when regex should produce nothing
cr...@animalhead.com wrote: ... But you left out one important caveat which could scare away more potential users than it saves. The retention of values from previous executions applies only to global variables. Ah, yes. But that would have triggered another discussion (which it might now still do of course), about what exactly /is/ a global variable, in the context of a mod_perl handler or perl script run under modperl::Registry. I must admit that I am not totally clear on that subject either. I understand the basic idea of scoping, but as to the fine distinctions between our and my variables defined/referenced within/without various functions defined in the same package, and what mod_perl makes of this package when it compiles it, I tend to get a bit confused. And I would not be surprised if the perl documentation to that effect confused a relative beginner even more. So again, to be defensive I find that the safest (if not most efficient/elegant) way is to just treat every variable as a potential problem, and make sure they are (re-)initialised unless I specifically don't want them to be. This is no critic to the writers of the perl and mod_perl documentation. I am sure that this particular topic is quite hard to get across clearly and succintly to perl plodders such as me. And I find the perl documentation, in general, extremely accessible and a treasure-trove of information (and not just about perl). It's just that on that particular topic I seem to be a bit thick, and considering that, I'd rather be safe than sorry.
Re: Getting a / when regex should produce nothing
On 04/24/10 21:38, Chris Bennett wrote: When I run this first time, with no values from form, I get $article_file being a / when it should be nothing. I just can't see the error. I have tried variations with \w and dash at beginning and end, but no go. Debug shows blank at A, / at B #!/usr/bin/perl $VERSION = 1.0.0; use warnings; no warnings 'uninitialized'; use strict; #use Apache::Constants qw(:common); use Apache::Request(); #use Apache::Cookie(); use MyPerl::Articulator qw(get_template print_template print_text submit_changes backup_server see_html template_form load_template); our $debug = 1; delete $ENV{PATH}; my $r = Apache-request; my $q = Apache::Request-new($r, POST_MAX = 100, DISABLE_UPLOADS = 1); my $site_url = www.example.com; my $site_directory = /var/www/htdocs/users/example.com; my $site_name = Example!; my $secure = 1; my $article_directory = articles; undef my $error; undef my $article_title; undef my $article_backup_file; undef my $article_file; $article_file = $q-param(articlefilename); if ($debug) { $error .= qq{p$article_file/p};} $article_file =~ m/^([a-zA-Z0-9_-]*\.html)$/; $article_file = $1; if ($debug) { $error .= qq{p$article_file/p};} $article_backup_file = $article_file; $article_backup_file =~ s/\.html$/_backup.html/; undef my $body; Thanks Chris Bennett OK, as per suggestions and adding in another needed part for MultiViews: my $error = ''; my $article_title =''; undef my $article_backup_file; undef my $article_file; $article_file = $q-param(articlefilename) || ''; if ($debug) { $error .= qq{pA $article_file/p};} if ($article_file =~ /^([a-zA-Z0-9_-]+\.html.?\w?\w?)$/) { $article_file = $1; } else { $article_file = ''; } if ($debug) { $error .= qq{pB $article_file/p};} $article_backup_file = $article_file; $article_backup_file =~ s/\.html$/_backup.html/; Is there a better regex for .?\w?\w? I want a . letter letter not . letter or just two letters etc. This regex is to prevent read or write access to files up the directory tree or non html files. There is also a username password for any write access. undef my $variable is not a common idiom but is seen in Programming Perl and other places. Is there any reason I should use my $variable = undef? More typing. :) Why was I getting a / back? Is that an artifact from the perl internals? Thanks
Re: Getting a / when regex should produce nothing
- Original Message From: Chris Bennett ch...@bennettconstruction.biz To: ch...@bennettconstruction.biz; modperl@perl.apache.org Sent: Sun, April 25, 2010 8:17:07 AM Subject: Re: Getting a / when regex should produce nothing Is there a better regex for .?\w?\w? I want a . letter letter not . letter or just two letters etc. (?:\.\w{2})? This regex is to prevent read or write access to files up the directory tree or non html files. There is also a username password for any write access. undef my $variable is not a common idiom but is seen in Programming Perl and other places. Is there any reason I should use my $variable = undef? More typing. :) What's wrong with just typing my $variable;? Why was I getting a / back? Is that an artifact from the perl internals? In your previous code you didn't check that the pattern had matched before using $1. In the case when your pattern doesn't match, $1 remains unchanged from whatever last set it. There's probably some code earlier on, or internal to mod-perl, which does a (successful) pattern match that sets $1 to /. The lesson here should be to always check the return value of your regexps for success, especially when you've used capture variables in your code like $1-$9.
Re: Getting a / when regex should produce nothing
Chris Bennett wrote: ... $article_file = $q-param(articlefilename) || ''; ok, so suppose it is 12345.html.en ... if ($article_file =~ /^([a-zA-Z0-9_-]+\.html.?\w?\w?)$/) { $article_file = $1; } else { $article_file = ''; } ok, matches, so it's still 12345.html.en $article_backup_file = $article_file; still 12345.html.en $article_backup_file =~ s/\.html$/_backup.html/; still 12345.html.en (because \.html$ did not match)
Re: Getting a / when regex should produce nothing
On 04/25/10 08:57, André Warnier wrote: Chris Bennett wrote: ... $article_file = $q-param(articlefilename) || ''; ok, so suppose it is 12345.html.en ... if ($article_file =~ /^([a-zA-Z0-9_-]+\.html.?\w?\w?)$/) { $article_file = $1; } else { $article_file = ''; } ok, matches, so it's still 12345.html.en $article_backup_file = $article_file; still 12345.html.en $article_backup_file =~ s/\.html$/_backup.html/; still 12345.html.en (because \.html$ did not match) I have since changed to: $article_file = $q-param(articlefilename) || ''; if ($debug) { $error .= qq{pA $article_file/p};} if ($article_file =~ /^([a-zA-Z0-9_-]+\.html(?:\.\w{2})?)$/) { $article_file = $1; } else { $article_file = ''; } if ($debug) { $error .= qq{pB $article_file/p};} $article_backup_file = $article_file; if ($article_backup_file =~ /\.html(?:\.\w{2})?$/) { $article_backup_file =~ s/\.html/_backup.html/; } else { $error .= pPlease choose an existing File Name ( like y_9-e.html or yyy.html.xx ) or use Fill in Template to create a new file./p; } I think this does the trick. Please feel free to break this! :)
Re: Getting a / when regex should produce nothing
André Warnier schrieb am 25.04.2010 um 12:44:56 (+0200): use warnings; That's good. But this : no warnings 'uninitialized'; is very dubious. I used to think so, too, but I've recently changed my mind. $article_file = $q-param(articlefilename); will come back undef if : - there is no articlefilename input box on the submitted form - there is one, but it is not sent by the browser (as some browsers may do if the form field has not been filled-in) - someone just calls your script by a URL in the location bar, without parameters True, the value will be undef, but so what? Perl treats undef as the empty string or zero depending on the context, regardless of whether you've resolved to have yourself harassed with warnings because of uninitialized values or not; if, however, you *have* done so, then you'll see those warnings on STDERR and feel that you should fix your code by doing something like: $str = $q-param(articlefilename) || ''; $num = $bla-calc_blub || 0; So you're performing manually what Perl does automatically just to get rid of the warning you've decided to turn on because you thought it was good, or robust, or solid. If you think about it, you have to admit that this is not exactly clever. if ($debug) { $error .= qq{p$article_file/p};} This then is dubious too, because you are essentially concatenating a string (which may also be undef), with an undef value. So what? The undef is automatically converted to an empty string. That's what you want anyway. Let Perl do it for you. (And before that, you are passing this undef value to the qq function). Who knows what this does ? Unfortunately, you will never know, because you have disabled warnings for that. There's probably no need to know in this case. If your fix is to convert undef to an empty string, why not have Perl do it for you? Why not do something more solid, like : remove the no warnings pragma. $article_file = $q-param(articlefilename) || ''; (making it equal to an empty string if it is undefined), or more explicitly $article_file = $q-param(articlefilename); $article_file = '' unless defined $article_file; And the same for any other form parameter you receive. I've been doing this for ten years now, but I've stopped, because it's tedious and, I think, pointless. Perl does it for you. If you are programming for the web, where you essentially do not know which miscreant browser or user is at the other end, you have to program defensively. Suppressing warnings is the wrong way to go. I wouldn't say so. Either you agree with Perl's automatic conversion of undef to '' or 0 depending on the context (which apparently you do when you write || '' or || 0), or you don't agree because you do not want to tolerate undef at all (because you're counting money, for example). In the former case, just do as the OP did (no warnings 'uninitialized'); in the latter case consider making your code really robust and the warning fatal. For the record, I've changed my mind about this uninitialized business after reading the perldoc for common::sense by Marc Lehmann: http://search.cpan.org/~mlehmann/common-sense-3.2/ -- Michael Ludwig
Getting a / when regex should produce nothing
When I run this first time, with no values from form, I get $article_file being a / when it should be nothing. I just can't see the error. I have tried variations with \w and dash at beginning and end, but no go. Debug shows blank at A, / at B #!/usr/bin/perl $VERSION = 1.0.0; use warnings; no warnings 'uninitialized'; use strict; #use Apache::Constants qw(:common); use Apache::Request(); #use Apache::Cookie(); use MyPerl::Articulator qw(get_template print_template print_text submit_changes backup_server see_html template_form load_template); our $debug = 1; delete $ENV{PATH}; my $r = Apache-request; my $q = Apache::Request-new($r, POST_MAX = 100, DISABLE_UPLOADS = 1); my $site_url = www.example.com; my $site_directory = /var/www/htdocs/users/example.com; my $site_name = Example!; my $secure = 1; my $article_directory = articles; undef my $error; undef my $article_title; undef my $article_backup_file; undef my $article_file; $article_file = $q-param(articlefilename); if ($debug) { $error .= qq{p$article_file/p};} $article_file =~ m/^([a-zA-Z0-9_-]*\.html)$/; $article_file = $1; if ($debug) { $error .= qq{p$article_file/p};} $article_backup_file = $article_file; $article_backup_file =~ s/\.html$/_backup.html/; undef my $body; Thanks Chris Bennett -- A human being should be able to change a diaper, plan an invasion, butcher a hog, conn a ship, design a building, write a sonnet, balance accounts, build a wall, set a bone, comfort the dying, take orders, give orders, cooperate, act alone, solve equations, analyze a new problem, pitch manure, program a computer, cook a tasty meal, fight efficiently, die gallantly. Specialization is for insects. -- Robert Heinlein
Re: Getting a / when regex should produce nothing
On 04/24/10 21:38, Chris Bennett wrote: When I run this first time, with no values from form, I get $article_file being a / when it should be nothing. I just can't see the error. I have tried variations with \w and dash at beginning and end, but no go. Debug shows blank at A, / at B #!/usr/bin/perl $VERSION = 1.0.0; use warnings; no warnings 'uninitialized'; use strict; #use Apache::Constants qw(:common); use Apache::Request(); #use Apache::Cookie(); use MyPerl::Articulator qw(get_template print_template print_text submit_changes backup_server see_html template_form load_template); our $debug = 1; delete $ENV{PATH}; my $r = Apache-request; my $q = Apache::Request-new($r, POST_MAX = 100, DISABLE_UPLOADS = 1); my $site_url = www.example.com; my $site_directory = /var/www/htdocs/users/example.com; my $site_name = Example!; my $secure = 1; my $article_directory = articles; undef my $error; undef my $article_title; undef my $article_backup_file; undef my $article_file; $article_file = $q-param(articlefilename); if ($debug) { $error .= qq{p$article_file/p};} should be if ($debug) { $error .= qq{pA $article_file/p};} $article_file =~ m/^([a-zA-Z0-9_-]*\.html)$/; $article_file = $1; if ($debug) { $error .= qq{p$article_file/p};} should be if ($debug) { $error .= qq{pB $article_file/p};}
Re: Getting a / when regex should produce nothing
See what happens if you replace the 2 lines between the should bes with if ($article_file =~ /^([a-zA-Z0-9_-]*\.html)$/) {$article_file = $1} I've can't recall seeing 'undef my' before. my $error = undef; is more typical. How is this routine executed? Under ModPerl::Registry? cmac On Apr 24, 2010, at 7:47 PM, Chris Bennett wrote: On 04/24/10 21:38, Chris Bennett wrote: When I run this first time, with no values from form, I get $article_file being a / when it should be nothing. I just can't see the error. I have tried variations with \w and dash at beginning and end, but no go. Debug shows blank at A, / at B #!/usr/bin/perl $VERSION = 1.0.0; use warnings; no warnings 'uninitialized'; use strict; #use Apache::Constants qw(:common); use Apache::Request(); #use Apache::Cookie(); use MyPerl::Articulator qw(get_template print_template print_text submit_changes backup_server see_html template_form load_template); our $debug = 1; delete $ENV{PATH}; my $r = Apache-request; my $q = Apache::Request-new($r, POST_MAX = 100, DISABLE_UPLOADS = 1); my $site_url = www.example.com; my $site_directory = /var/www/htdocs/users/example.com; my $site_name = Example!; my $secure = 1; my $article_directory = articles; undef my $error; undef my $article_title; undef my $article_backup_file; undef my $article_file; $article_file = $q-param(articlefilename); if ($debug) { $error .= qq{p$article_file/p};} should be if ($debug) { $error .= qq{pA $article_file/p};} $article_file =~ m/^([a-zA-Z0-9_-]*\.html)$/; $article_file = $1; if ($debug) { $error .= qq{p$article_file/p};} should be if ($debug) { $error .= qq{pB $article_file/p};}