in reply to Re: Re: optimization - exists should return a reference
in thread optimization - exists should return a reference

Yes, that's exactly what I'm saying.

If exists is to return a reference, it should always return a reference. Code exists which says exists( $foo{'bar}) ? 'Exists' : 'Does not exist'. That code will break if exists returns a reference, because references always evaluate true.

If what we get from exists is a reference, we should be able to treat is like any other reference. You seem to want to be able to assign from it and dereference the copy, but deny the ability to dereferencee it directly.

Just how is that supposed to work?

After Compline,
Zaxo

Replies are listed 'Best First'.
Re: Re: Re: Re: optimization - exists should return a reference
by BrowserUk (Patriarch) on Jan 15, 2003 at 19:56 UTC

    Sorry Zaxo. I know I'm being thick here, but if the entity being testing for existance doesn't exist, exists can't return a reference to it. And if it did return a "false reference", you wouldn't be able to do anything with it except test it for being false, so it should just return false, whether that is undef, 0, or '' makes no difference. As long as it returns false, then existing code like

    print exists( $foo{'bar'} ) ? 'Exists' : 'Doesn't exist';

    doesn't break.

    I'm sure I missing the salient point here, but I can't see where.


    Examine what is said, not who speaks.

    The 7th Rule of perl club is -- pearl clubs are easily damaged. Use a diamond club instead.

Re: Re: Re: Re: optimization - exists should return a reference
by sauoq (Abbot) on Jan 16, 2003 at 01:42 UTC

    Right now, we can only use exists as a boolean. The suggestion is to extend it so that when the value returned is true that value is itself useful.

    Assume for a minute that the hypothetical reference-that-evaluates-to-false-in-boolean-context actually could be returned... what use would it be to dereference it anyway?

    If you really wanted something like that, you could forge it yourself:

    my $bar = ${exists($foo{bar}) || \undef};

    -sauoq
    "My two cents aren't worth a dime.";
    
Re^4: optimization - exists should return a reference
by LAI (Hermit) on Jan 15, 2003 at 20:31 UTC

    "If exists is to return a reference, it should always return a reference."

    I don't know about that. Let's say we're looking at exists($foo{'bar'}). So, if $foo{'bar'} exists, exists returns a reference to it. Otherwise, it returns undef or an empty string, or 0 or whatever the hell. Something that's false in a boolean context. One potential problem, as you point out, is if someone tries to dereference the result without checking to see if it's true first. (I'll assume for the time being that it's out of the question to change the way references evaluate in boolean context :o)

    I would say that checking for the existance of the value returned by exists is pretty natural. For instance the example put forward by BrowserUK:

    use strict 'refs'; print ${exists $foo{'bar'}};

    would yield Can't use an undefined value as a SCALAR reference or something of the like. This would be an example of bad coding: using a value without being sure that there is a value. It's really no different from: The same mistake is made (and the same error potentially generated) as if the following were written:

    use strict 'refs'; print ${$foo{'bar'}};

    This would yield the same error. Whereas one 'right' way to do the same thing would be:
    One 'right' way to use the reference from the proposed exists would be:

    use strict 'refs'; print ${exists $foo{'bar'} || \"" };

    ...perhaps substituting a reference to a default value or somesuch for the \"". What I'm saying is that this puts responsibility on the programmer to make sure she doesn't try to dereference anything undefined or whatever. If she wants to be able to do stuff like print ${exists $foo{'bar'}} she's not going to use strict. For the rest of us, we get added functionality for exists that doesn't break existing code.

    Update: The crux, in my mind, of why print ${exists $foo{'bar'}} doesn't make sense just finally came to me in actual words: it's like writing print ( if ($foo{'bar'}) ), or print ( $foo > $bar ). It's a boolean test, which is not designed to stand alone. Conceptually, exists exists to choose between two options.

    Update: Aristotle pointed out some ambiguity in the way I phrased some stuff. Also, I noticed that in my first paragraph I had written exists $foo instead of exists $foo{'bar'}.


    LAI
    :eof
      print ${exists $foo{'bar'}}; # ... print ${$foo{'bar'}};
      These differ. The former would print the value of $foo{bar}, the latter of ${$foo{bar}}.

      Makeshifts last the longest.

        Sorry, my fault for not being clear. I wrote:

        print ${exists $foo{'bar'}}; #[...][is] really no different from: print ${$foo{'bar'}};

        When what I meant is that either can be considered 'wrong' for the same reason: that they may be undef or scalar or whatnot, therefore breaking the dereference.


        LAI
        :eof