jeanluca has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,

I just wrote a small script:
#! /usr/bin/perl @a = &test() ; if ( defined @a) { print "defined\n" ; } sub test { return undef ; }
Guess what, it prints defined!!
Of course this is not what I want. What I would like to know is why this happens and how to solve this ?

Thanks a LOT in advance
Luca

Replies are listed 'Best First'.
Re: if (defined @arr) problem
by secret (Beadle) on Dec 15, 2005 at 10:07 UTC
    That's because the array contains one value : 'undef' .
    Look at what happens if you do :
    sub test { return () ; }
    You can also print scalar @a to see the what's the length of the array .

      That's because the array contains one value : 'undef' .
      That looks like a string with the text "undef" to me. That's not what the array contains. Instead, it holds an undefined scalar value.

      Look at what happens if you do :
      sub test { return () ; }

      Lo and behold, it works!

      Still, testing definedness of an array is a very bad idea. Try running this code first:

      @a = qw(a b c);
      and now you'll see, the array will be defined (and empty).

      Don't. Do. It.

      Definedness of an array is nothing a newbie should ever be concerned about.

          Still, testing definedness of an array is a very bad idea. Try running this code first:
          @a = qw(a b c);
        Ah yes :) that's very true !  scalar @array is, of course, much better !

        ( i did meant the undef value, btw, and not the string 'undef' but it's true that my use of single quotes was indeed a bad idea !! )

        I'll add something : suppose the OP wanted to undef arrays in a sub . I think I would pass the array as a reference, undef it in the sub and return the reference .

        > Still, testing definedness of an array is a very bad idea.
        > Try running this code first: 
        >
        > @a = qw(a b c);
        >
        > and now you'll see, the array will be defined (and empty).
        

        Hmm, i get "defined: yes" and "size: 3" ...

        @a = qw/a b c/; printf "defined: %s\nsize: %d\n" , defined @a ? 'yes' : 'no' , scalar @a ;

        ... what did i miss?

Re: if (defined @arr) problem
by Hue-Bond (Priest) on Dec 15, 2005 at 10:10 UTC

    Do not use & unless you know what you are doing.

    Running your code under strict and warnings yields a message about using defined for arrays and invites to use just @a.

    use strict; use warnings; sub test { undef; } my @a = test; if (@a) { use Data::Dumper; print Dumper \@a; } __END__ $VAR1 = [ undef ];

    I hope this answers your question.

    --
    David Serrano

Re: if (defined @arr) problem
by Perl Mouse (Chaplain) on Dec 15, 2005 at 10:23 UTC
    What happened is that you returned a list containing one element - the element being undef. So, @a is a one element array, and hence is certainly defined.

    The Perl documentation warns you about using defined on aggregates. Usually, Perl is very DWIM, but in this case, it isn't. The return values are usually surprising, and while p5p has talked about changing this, it hasn't happened yet.

    If you want to find out whether an array has elements in it, just use the array in boolean (scalar) context. It will return a true value if there are elements in it, or else it will return a false value.

    Perl --((8:>*
Re: if (defined @arr) problem
by blazar (Canon) on Dec 15, 2005 at 14:13 UTC
    Curiously enough perldoc -f defined has something to say about this:
    Use of "defined" on aggregates (hashes and arrays) is depre- cated. It used to report whether memory for that aggregate has ever been allocated. This behavior may disappear in future versions of Perl. You should instead use a simple test for size:
Re: if (defined @arr) problem
by murugu (Curate) on Dec 15, 2005 at 10:28 UTC

    It prints defined because it is having a a value undef inside it. It gave me warning that defined(@array) is depreciated ;-(

    Regards,
    Murugesan Kandasamy
    use perl for(;;);