Re: -w in production environment
by tachyon (Chancellor) on Jul 05, 2001 at 23:21 UTC
|
Eliminating -w is one option that will work and is reasonable if you have completely debugged all the code...If you find a reliable method please tell me how! Another option is to initialise all your values. It depends on how your script is structured as to how you do this. Say you are using CGI.pm, here is what you usually find at the top of my scripts:
#!/usr/bin/perl -wT
use strict;
use CGI;
my $q = new CGI;
my $var = $q->param('var') || '';
untaint(\$var);
# warning do not do this
my @ary = $q->param('options') || ();
# this kills the array return of CGI.pm
If you use param queries directly you can do this to define all undefined values:
my @fields = qw(foo bar baz);
for (@fields) {
$q->param($_,'') unless defined $q->param($_);
}
This iterates over the field names an pushes a null string into the value if it is not defined. You can use the same method for a hash:
my @fields = qw (foo bar baz);
for (@fields) {
$USER{$_} = '' unless defined $USER{$_};
}
Use strict does have an overhead (a very small overhead) - try benchmarking if you are really worried and execution speed is everything. Use mod perl in this case! The reason for leaving use strict and -w active is that your code *will* be modified one day, perhaps by you, perhaps not. If they are active no one has to to remember to reactivate them. If you must kill them comment them out rather than erase them entirely with a note that the should be used for testing modifications to the code.
cheers
tachyon
s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
Use strict does have an overhead
?? Well, that is pretty darn misleading. use strict has a very, very tiny overhead such that most people that I respect and who I've heard weigh in on the subject feel that the work of adding and removing strict between testing and production (and more importantly, the risk of forgetting to add it back in each time changes are made) outweigh the cost by a wide margin.
Taint checking is also something that should not be disabled in production (even more so than strict).
Warnings, however, are much easier to justify removing from production. Perhaps the best situation would be to keep warnings enabled but have a separate infrastructure for collecting warnings information and making sure the volume of information can't become a burden.
But if you don't create a separate infrastructure for warnings, I'd definitely turn them off in production.
-
tye
(but my friends call me "Tye")
| [reply] [Watch: Dir/Any] |
|
Hi, it's not misleading at all. *Every* operation in Perl has an overhead - including use strict.
As the question was "does use strict have an overhead?" the answer is/was correct.
I then went on to suggest benchmarking and mod Perl if speed was the critical issue and then
additionally suggest reasons not to disable use strict and -w....as you reiterated....
cheers
tachyon
s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print
| [reply] [Watch: Dir/Any] |
Re: -w in production environment
by Abigail (Deacon) on Jul 06, 2001 at 02:45 UTC
|
I agree with people that you should keep -w in production
code. Sure, it does mean you might have to add some more code where you
otherwise could get away with cutting corners. But if later the customer
comes with "it doesn't work", and you have nothing else to fall back on
(nothing in the error logs), it might be hard to fix the problem, while
it would have been trivial if you had the warning(s).
I am however surprised about the suggested "fixes" several of the previous
posters gave. Just checking whether $USER {coffee} exists or
is defined fixes all possible warnings! Sure, it avoids the
use of uninitialized value warning, but clearly, the form input
hasn't been checked for sanity! What if $USER {coffee}
contains Java? Argument "java" isn't numeric in
numeric gt isn't much better as warning message.
You cannot trust form input. Don't assume it's there, and don't assume
it's in the format you want it to be. Don't assume it's a number just
because you are going to use it as a number.
-- Abigail
| [reply] [Watch: Dir/Any] [d/l] [select] |
Re: -w in production environment
by chromatic (Archbishop) on Jul 06, 2001 at 01:59 UTC
|
One other option is to add your own warn handler that ignores uninitialized value warnings. Personally, I'd rather deal with them in the code so as to avoid nasty surprises, but it can come in handy sometimes:
$SIG{__WARN__} = sub {
unless ($_[0] =~ /^Use of uninitialized value/) {
warn $_[0];
}
};
Looks like there's more information in warn and perlvar. | [reply] [Watch: Dir/Any] [d/l] |
Re: -w in production environment
by clintp (Curate) on Jul 05, 2001 at 23:27 UTC
|
Regardless of whether or not you're using CGI.pm (that's none of my business) you should leave the warnings on anyway. It's going to catch other problems eventually and that's a Good Thing.
Lots of gratuitous errors in the log will cause people to ignore the log...So...
If you honestly expect a lot of blank fields, and the prospect of checking for defined-and-then-a-value makes you nauseous, just pre-cook them all with a defined value (like the empty string) before you use them:
for(keys %USER) {
$USER{$_}="" unless defined $USER{$_};
}
| [reply] [Watch: Dir/Any] [d/l] |
Re: -w in production environment
by clscott (Friar) on Jul 05, 2001 at 23:52 UTC
|
if (exists $USER{coffee} && $USER{coffee} > 5){$msg='You drink too muc
+h coffee'}
It checks that the coffee key exists in %USER.
You can just use
if ($USER{coffee} && $USER{coffee} > 5){$msg='You drink too much coffe
+e'}
It will get rid of the warning, but won't actually do anything useful. exists checks that the coffee key was created. This check actually tells you a potentially relevant piece of information.
e.g
if (! exists $USER{coffee}){
$msg = 'You drank no coffee?!?!';
}
elsif ($USER{coffee} > 5){
$msg='You drink too much coffee';
}
else {
$msg='You drank a moderate amount of coffee';
}
There is no point in adding code just to get rid of a warning if the new code does nothing useful! It is a poor practice to get into and can be confusing to the people that have to maintain you application. Like Abigail said check your input to make sure no one made a mistake inputting a value (or is pulling a fast one on you).
This doesn't seem to be the behaviour that you want.
HTH,
Clayton
Update:
I removed a section that said testing if a non exsistant key was defined would autovivify it and added my support for Abigail's answer. I swear with God as my witness... | [reply] [Watch: Dir/Any] [d/l] [select] |
|
If you used defined $USER{coffee} as a check it will actually autovivify (automatically create) the coffee key as it does when you do your current test.
That's not true:
use warnings;
use strict;
my %c = ( hey=>'Joe',
where=>'you goin\'',
with=>'that gun in your hand');
if (defined $c{Hendrix}) {
print "Jimi is alive and well\n";
}
foreach ( sort keys %c ) {
print "Key : $_ => $c{$_}\n";
}
This does not print "Hendrix" and yield up a warning on the loop that goes through the keys (Perl 5.6.1, Win32).
Of course defined $hash{key} and exists $hash{key} do test for different things:
$hash{key} = undef; #defined $hash{key} false, exists $hash{key} true
perl -e 'print "How sweet does a rose smell? "; chomp ($n = <STDIN>);
+$rose = "smells sweet to degree $n"; *other_name = *rose; print "$oth
+er_name\n"'
| [reply] [Watch: Dir/Any] [d/l] [select] |
Re: -w in production environment
by converter (Priest) on Jul 05, 2001 at 23:12 UTC
|
You didn't mention if you were using CGI.pm or not, but I'll assume that you are since most good Perl programmers use it. :)
&CGI::param should returned the undefined value only for those fields left blank by the user, a value of zero is not undefined, so I doubt fields filled with zero are causing a warning. To accomodate possible empty fields, check the value returned by param() and if it is not defined, assign an empty string or zero, whichever is appropriate. Something like:
$USER{coffee} = param('coffee') || 0;
| [reply] [Watch: Dir/Any] [d/l] |
Re: -w in production environment
by epoptai (Curate) on Jul 05, 2001 at 23:56 UTC
|
if ($USER{coffee} && $USER{coffee} > 5){
$msg = 'You drink too much coffee'
}
It's still redundant, but that's part of the point of using
warnings. Warnings seem to make perl assume less about
what you mean, so you need to tell it more about what you
want. In my experience strict and warnings compliant
code is always larger and slower than 'casual' freestyle
perl code, but for large scripts the price is well worth
what it buys in security and stability.
Update: Abigail makes a good point about sanity
checking. For that perl needs more information about
what we expect our input to contain:
if ($USER{coffee} && $USER{coffee} =~ /\d+/){
$msg = 'You drink too much coffee' if $USER{coffee} > 5;
}
--
Check out my Perlmonks Related Scripts like framechat,
reputer, and xNN.
| [reply] [Watch: Dir/Any] [d/l] [select] |
Re: -w in production environment
by scain (Curate) on Jul 05, 2001 at 22:53 UTC
|
I don't see why a response of 0 would give an uninitialized warning.
Are you sure it does? I was going to suggest putting default
responses in the html form to eliminate the warnings, but if
you are getting the response in the way you indicate, default
responses may not fix it.
Scott
| [reply] [Watch: Dir/Any] |
|
I'm not sure if this is browser dependant or not, but upon posting a html form with a zero value, I have found many times that the element is not passed through to the script.
I am using CGI.pm
Greg
| [reply] [Watch: Dir/Any] |
Re: -w in production environment
by Zaxo (Archbishop) on Jul 05, 2001 at 23:00 UTC
|
Sorry, but I think those warnings are telling you you haven't finished the job. You're still debugging, so that's ok.
Obligatory Question: you are using CGI.pm, aren't you?
After Compline, Zaxo
| [reply] [Watch: Dir/Any] |
Re: -w in production environment
by blakem (Monsignor) on Jul 05, 2001 at 23:03 UTC
|
I believe use strict catches mostly
compile-time errors, and it does take time to run (and pull
in the extra code.) If you are really pining for those extra few miliseconds, its probably "safe" to remove it from
production code. However, i've found it to be more of
a hassle than its worth..... I usually prefer to just leave the use strict in the production code.
-Blake
| [reply] [Watch: Dir/Any] [d/l] [select] |
Re: -w in production environment
by Anonymous Monk on Jul 05, 2001 at 23:28 UTC
|
I'm not sure if this is a solution you will want to use but
here is what I usually do.
Instead of
if ($USER{coffee} > 5){ ... }
I would use
if (defined($USER{coffee}) && $USER{coffee} > 5) { ... }
I feel checking defindedness is good thing to do in any case.
| [reply] [Watch: Dir/Any] [d/l] [select] |