Re^2: Breaking The Rules
by GrandFather (Saint) on May 30, 2006 at 22:32 UTC
|
use warnings;
my $var=1;
print $var;
Why the test? If $var is undef something much more serious is going on and I want to know about it.
Yes, I know this is a trivial example and you imply that there may be legitimate situations in which $var is undef. However I'm suggesting that if $var is undef when you are about to print its contents, then there is a flaw in the code. It may be as trivial as not having provided a default value, but providing the default value is important - it says to the reader that you have thought about the special case of the variable contents haven't been changed.
BTW, your second version is needlessly convoluted and will generate a warning (two if $var is undefined). KISS
DWIM is Perl's answer to Gödel
| [reply] [d/l] |
|
However I'm suggesting that if $var is undef when you are about to print its contents, then there is a flaw in the code.
Its seldom a 'flaw in the code' if you need to check whether something has been defined. It could be a flaw from, say, user supplied input and your code needs to differentiate between data that was missing entirely (undef) and an empty string or 0.
while (<FILE1>) {
$var = GetVar($_);
};
if ($var eq undef) {
die "File provided doesn't include var!\n";
}
You can't rely on warnings to tell you var didn't exist in the file, and you have no control over whether var gets defined.
Also, there are benefits to "define when needed" if you have a complex set of processing which may or may not require a particular variable in numerous places and its impossible to predict which loop is going to need the variable first, if at all. Rather than needlessly calculating it before starting, just check for undef wherever you use it.
There are countless legitimate reasons why you'd want to check whether a variable has been defined, and its not a rare occurrence.
BTW, your second version is needlessly convoluted and will generate a warning (two if $var is undefined). KISS
That's the point of my example; the fact that it throws a warning (or two), and its not needlessly convoluted (although the opinion of convolutedness apparently varies). In fact, it provides more symmetry if your doing something like
if ($var eq undef) {
...
} elsif ($var eq '') {
...
} elsif ($var eq 'foo') {
...
};
| [reply] [d/l] [select] |
|
I agree absolutely that there are often times when you need to check to see if something is defined in Perl. I was questioning the use of the test in a context where it looks like the variable should have been validated long ago - a rather bold interpretation of the example code I agree.
The important point here is to distinguish between cases where it is expected that a variable may be undefined as a result of previous processing (defined should be used to test that), and where a variable is undefined because of a flaw in previous processing - in which case use warnings catches the problem as early as possible and is extremly useful.
That's the point of my example; the fact that it throws a warning (or two)
In that case your example is gratuitiously idiosyncratic. The language provides a clean way of testing for a defined value. Why bend over backwards to avoid using defined?
While Its seldom a 'flaw in the code' if you need to check whether something has been defined, it is almost always a flaw in the code if use warnings generates an undefined used type warning. Comparing with undef is flawed, if only because you lose the virtue of turning on warnings.
DWIM is Perl's answer to Gödel
| [reply] [d/l] [select] |
|
|
|
|
You can't rely on warnings to tell you var didn't exist in the file, and you have no control over whether var gets defined.
Not true:
while (<FILE1>) {
$var = GetVar($_) || $some_reasonable_default;
};
$var is now guaranteed to have a defined value on every iteration, regardless of the file's contents. Granted, there are cases where there is no reasonable default, but, as the programmer, I do still have control over whether $var is defined or not, should I choose to exercise it. | [reply] [d/l] |
|
|
|
|
if ($var eq undef) {
...
} elsif ($var eq '') {
...
} elsif ($var eq 'foo') {
...
};
As noted several times, 'eq' isn't "equals" it is "string equals" (and '==' is "number equals"). If you want to compare to 'undef', then you want 'given' (or 'when' or '~~', Perl6isms that'll appear in Perl5 soon enough -- I'd say more but searching for "given" is pretty useless, since I see patches to add them already being applied).
| [reply] [d/l] |
Re^2: Breaking The Rules
by Anonymous Monk on May 31, 2006 at 20:00 UTC
|
Your two ways of testing undef don't actually do the same thing.
if defined $var will execute your statement if $var is defined. unless $var eq undef will execute your statement if $var is undef, the empty string, or something else that will stringify to the empty string. Try the following code snippet to see for yourself:
my $var = undef;
print "Undefined!\n" if $var eq undef;
$var = '';
print "Undefined again!\n" if $var eq undef;
This happens because the "eq" operator stringifies both of its arguments, and undef stringifies to the empty string.
The warning doesn't exist just to critique your syntax... it's warning you of a danger that your code might not be doing exactly what you think it is. | [reply] [d/l] [select] |
|
| [reply] |
Re^2: Breaking The Rules
by spiritway (Vicar) on Jun 02, 2006 at 03:31 UTC
|
The thing about use warnings; is that it helps you to avoid subtle, sneaky errors that you would otherwise have a very difficult time tracking down. I'll gladly put up with a few spurious warnings, versus spending many hours of head-banging debug time trying to find where I slipped up. For me, use warnings; has paid for itself many times over.
As is so often the case, YMMV. I've never encountered anything like the situation you mention. Perhaps I'm not sufficiently advanced; perhaps it's just coding styles. If I ran into problems more often, I might agree with you and stop using warnings. To date, though, this nit-picky little pragma has saved me much aggravation and gnashing of teeth, muttering evil phrases, and all that fun stuff we're so good at.
| [reply] [d/l] [select] |
Re^2: Breaking The Rules
by runrig (Abbot) on May 31, 2006 at 21:09 UTC
|
is there really any benifit to writing...(snip)...other than to avoid the warnings?
Yes, the former is more clear in its intent, the latter is a longer and more obfuscated way of writing print $var unless $var eq '' (update: and even that may as well be just print $var ...printing an empty string shouldn't make a difference anyway...though I assume this is just a simple example and you could have, e.g., print "blah blah $foo blah" unless defined $foo)
| [reply] [d/l] [select] |