Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Exists and arrays

by deepakg (Novice)
on Oct 01, 2009 at 09:52 UTC ( [id://798579]=perlquestion: print w/replies, xml ) Need Help??

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

Hi Folks, Consider an array
@dow = (); $dow[6] = "Sat";
Now exists $dow[5] returns false. I expected exists($dow[5]) to be true and defined($dow[5]) to be false. Also dumping the array (Dumper(\@dow)) shows [undef, undef, undef, undef, undef, "Sat"]. If I do $dow[5] = undef; and then do exists($dow[5]) returns true. How does exists work for arrays - do I have to explicitly initialize an element before it "sees" it? I am on perl 5.10.0 on Snow Leopard. Thanks, Deepak

Replies are listed 'Best First'.
Re: Exists and arrays
by AnomalousMonk (Archbishop) on Oct 01, 2009 at 10:01 UTC
    Quoth  perldoc -f exists
    exists EXPR Given an expression that specifies a hash element or array element, returns true if the specified element in the hash or array has ever been initialized, even if the corresponding value is undefined. The element is not autovivified if it doesn't exist.
    See exists.
Re: Exists and arrays
by ccn (Vicar) on Oct 01, 2009 at 10:04 UTC
    from perldoc -f exists: Given an expression that specifies a hash element or array element, returns true if the specified element in the hash or array has ever been initialized, even if the corresponding value is undefined.

    My perl behaves the same way

    This is perl, v5.8.8 built for i486-linux-gnu-thread-multi
Re: Exists and arrays
by johngg (Canon) on Oct 01, 2009 at 13:29 UTC

    This code might help to illustrate what is happening.

    $ perl -le ' > print q{Elem. Exists Defined True Value}; > @ny = ( q{no }, q{yes } ); > $arr[ 9 ] = 9; > $arr[ 0 ] = 0; > $arr[ 1 ] = q{one}; > @arr[ 3 .. 5 ] = ( undef ) x 3; > $arr[ 7 ] = q{}; > print > qq{[ $_ ]: }, > $ny[ exists $arr[ $_ ] ], > $ny[ defined $arr[ $_ ] ], > $arr[ $_ ] ? $ny[ 1 ] : $ny[ 0 ], > $arr[ $_ ] > for 0 .. $#arr;' Elem. Exists Defined True Value [ 0 ]: yes yes no 0 [ 1 ]: yes yes yes one [ 2 ]: no no no [ 3 ]: yes no no [ 4 ]: yes no no [ 5 ]: yes no no [ 6 ]: no no no [ 7 ]: yes yes no [ 8 ]: no no no [ 9 ]: yes yes yes 9 $

    I hope this is helpful.

    Cheers,

    JohnGG

Re: Exists and arrays
by ikegami (Patriarch) on Oct 01, 2009 at 15:26 UTC
    exists is useless on arrays. Please use defined or check the index against the length of the array.
Re: Exists and arrays
by biohisham (Priest) on Oct 01, 2009 at 11:38 UTC
    The element $dow[5] exists in the array since you've treated it as an lvalue and assigned to it when you did $dow[5]=undef the second time you checked for existence. Why the first time checking for (exists $dow[5]) returns you false is obviously because it had nothing assigned to it and that there's no implication if $dow[6] does exist that $dow[5] has to automatically exist.
    Being defined is not related to existence, a variable can exist but it doesn't necessarily mean it is defined as is the case when you want to flush out a variable value.Another thing, a return value of undef can indicate many things, as operation failure, end of file...etc

    Exists checks whether a variable is existing in the array, that is, it has a value associated with it as a result of assignment (i.e. $dow[0]=undef), this is clearly indicated in Perl documentation for Functions, check out both defined and exists functions to decloud the confusion

    #!/usr/local/bin/perl use strict; my @dow=(); #array initialization is different from indexes initiali +zation $dow[0]=undef; $dow[6]= "sat"; for(my $i=0; $i <=6;$i++){ if(!(defined($dow[$i]) || exists($dow[$i]))){print "\$dow[$i] +\t not defined\n";} if(exists($dow[$i]) && !defined($dow[$i])){ print "\$dow[$i]\t +exists\t not defined\n"; } if(exists($dow[$i]) && defined($dow[$i])){ print "\$dow[$i]\te +xists\t defined\n" ;} }

    Excellence is an Endeavor of Persistence. Chance Favors a Prepared Mind.
Re: Exists and arrays (Dumper)
by toolic (Bishop) on Oct 01, 2009 at 13:19 UTC
    Perhaps the Data::Dumper output is a little misleading in this case. I do see an assignment to undef in the source code:
    elsif (!defined($val)) { $out .= "undef"; }

    Maybe Dumper needs to print out something for non-existent array elements. Maybe it loosely uses 'undef' to mean both undefined and non-existent. If you print the Dumper output before and after your $dow[5] = undef; assignment, they are the same. You can play around with the source code if you really want to get to the bottom of this mystery.

Re: Exists and arrays
by deepakg (Novice) on Oct 03, 2009 at 18:47 UTC

    Thanks everyone for your replies

    I was assuming that the initialization of elements 0 to 5 was implicitly done by perl.

    From Learning Perl 5th Ed. If you store an array element that is beyond the end of the array, the array is automatically extended as needed - there's no limit on its length, as long as there's available memory for Perl to use. If Perl needs to create intervening elements, it creates them as undef values.

    So this led me to expect that exists would work here while defined won't. Of course the dumper output doesn't help the confusion.

      If you store an array element that is beyond the end of the array, the array is automatically extended as needed - there's no limit on its length, as long as there's available memory for Perl to use. If Perl needs to create intervening elements, it creates them as undef values.
      This is just correct enough to be misleading. Assigning to an OOB element of an array @a modifies $#a, and (I assume) Data::Dumper is using $#a to decide how big @a is. (See STORESIZE in perltie.) It's true that trying to access ‘intervening’ elements will return undef, but it's not true that those elements were ‘created’ by the STORESIZE.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (2)
As of 2024-04-25 20:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found