Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Re^4: Breaking The Rules

by GrandFather (Saint)
on May 31, 2006 at 16:49 UTC ( [id://552866]=note: print w/replies, xml ) Need Help??


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

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

Replies are listed 'Best First'.
Re^5: Breaking The Rules
by Unanimous Monk (Sexton) on May 31, 2006 at 19:35 UTC
    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.

      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.

      I do. To my mind, undef is not a value, it is the absence of a value. eq tests whether two values are equal, so applying it to the absence of a value (undef) seems rather odd.

      Or, to look at it another way, what you're really trying to do is to determine whether $var is defined or not, so defined $var seems like the obvious way of doing so. $var eq undef looks to me like you're checking to see whether $var has a certain value rather than checking to see if it's defined.

      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.

      Well, it really depends on what you think "eq" should do, and how it should work. There are benefits to both approaches, I think.

      If you think "eq" should compare two strings, then comparing one string against something that is specifically a special value that is *NOT* a string should flag a warning. (Let's assume warnings are always turned on for the purposes of this discussion.)

      If you think that "eq" should tell you whether two things are "set the same", then "eq" should "compare silently" to undef(); that is, the comparison should not generate a warning a string is compared to undef. This has the advantage of convenience and simplicity, but it also has a few drawbacks.

      In this alternative definition of "eq", to be consistant, you probably want every undefined expression to compare silently equal to every other undefined expression. If you do that, however, you might not catch all the kinds of errors that you may want to catch. For example, the following code will flag a warning under the current meaning of "eq", but wouldn't for the alternative meaning.

      $x = input_line(); # input_line returns undef on failure $y = input_line(); if ( $x eq $y ) { # checks to see if both lines are equal }

      Of course, you could always make "eq" have a third, more complicated definition: (a) when two strings are compared, "eq" generates warnings if one string is undefined, BUT (b) when one string and the constant "undef" are compared, "eq" will not generate any warnings.

      This third definition would probably work, but I'm not convinced it's any simpler than the existing system. Right now, all you have to decide is whether the comparison involves undef, or if it doesn't. The third definition requires that you distinguish between two subtly different "undefined values": the undefined value that comes from an expression vs. the undefined value that comes from a special constant. That sounds like too much work to me!

      The current definition of "eq" (and other comparison operators) seems like the simplest tradeoff between convenience, and power that I can think of, so that's why I favour it, despite the initial awkwardness of getting used to using defined() all the time.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://552866]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (3)
As of 2024-04-26 04:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found