in reply to Re: Breaking The Rules
in thread Breaking The Rules

I would write:

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

Replies are listed 'Best First'.
Re^3: Breaking The Rules
by Unanimous Monk (Sexton) on May 31, 2006 at 15:43 UTC
    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') { ... };

      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
        In that case your example is gratuitiously idiosyncratic. The language provides a clean way of testing for a defined value.

        I guess that’s my own idiosyncrasy. To me, it seems odd to use 'defined $var', if what you really want to do is check whether the value of $var is undef. I'd be curious to know how many other monks would think '$var eq undef' is idiosyncratic.

        Why bend over backwards to avoid using defined?

        It comes down to what you actually want to test for. While '$var eq undef' vs 'defined $var' return the same result, which one should be used should depend on the purpose of the check. When writing my post, I choose between words that have very similar meanings to get the correct point across (like using 'spurious' rather than, say, 'bogus'). Same thing when choosing syntax.

        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. If I'm asking "what is the value of $var" and I get the response 'undef', to me that means '$var eq undef'

        I don't dispute this point. If you use warnings, then '$var eq undef' will generate spurious warnings, so use 'defined $var' instead.

      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.
        Regardless of when/how you make $var = $some_resonable_default, immediately prior to you giving it a default value, it was legitimately undefined for reasons beyone your control. i.e. Just prior to evaluating the RHS of ||, $var was undefined and you had no control over it.
      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).

      - tye