How can I write "print $F[4] if exists $F[4]" even simpler?

Discussion in 'Perl Misc' started by jidanni@jidanni.org, Mar 4, 2010.

  1. Guest

    How can I write
    print $F[4] if exists $F[4];
    even simpler?
    print if exists for $F[4];
    print if exists $_ for $F[4];
    don't work.
    , Mar 4, 2010
    #1
    1. Advertising

  2. Uri Guttman Guest

    >>>>> "j" == jidanni <> writes:

    j> How can I write
    j> print $F[4] if exists $F[4];
    j> even simpler?
    j> print if exists for $F[4];
    j> print if exists $_ for $F[4];
    j> don't work.

    well, exists is for checking if a key exists in a hash. you don't have
    any hashes there so of course it won't work.

    uri

    --
    Uri Guttman ------ -------- http://www.sysarch.com --
    ----- Perl Code Review , Architecture, Development, Training, Support ------
    --------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
    Uri Guttman, Mar 5, 2010
    #2
    1. Advertising

  3. Frank Seitz Guest

    Uri Guttman wrote:
    >>>>>> "j" == jidanni <> writes:

    >
    > j> How can I write
    > j> print $F[4] if exists $F[4];
    > j> even simpler?
    > j> print if exists for $F[4];
    > j> print if exists $_ for $F[4];
    > j> don't work.
    >
    > well, exists is for checking if a key exists in a hash. you don't have
    > any hashes there so of course it won't work.


    No, exists() checks array elements, too. See perdoc -f exists.

    Frank
    --
    Dipl.-Inform. Frank Seitz
    Anwendungen für Ihr Internet und Intranet
    Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

    Blog: http://www.fseitz.de/blog
    XING-Profil: http://www.xing.com/profile/Frank_Seitz2
    Frank Seitz, Mar 5, 2010
    #3
  4. Uri Guttman Guest

    >>>>> "FS" == Frank Seitz <> writes:

    FS> Uri Guttman wrote:
    >>>>>>> "j" == jidanni <> writes:

    >>

    j> How can I write
    j> print $F[4] if exists $F[4];
    j> even simpler?
    j> print if exists for $F[4];
    j> print if exists $_ for $F[4];
    j> don't work.
    >>
    >> well, exists is for checking if a key exists in a hash. you don't have
    >> any hashes there so of course it won't work.


    FS> No, exists() checks array elements, too. See perdoc -f exists.

    even so, it is a useless concept IMO. array elements can be never
    allocated or filled with undef and there is little reason to know the
    difference. this is unlike knowing if a key exists regardless of its
    value being set with undef or never being set. exists was changed to
    support arrays because of pseudohashes which now are obsolete and
    removed from perl. maybe they should remove the array side of exists
    too.

    uri

    --
    Uri Guttman ------ -------- http://www.sysarch.com --
    ----- Perl Code Review , Architecture, Development, Training, Support ------
    --------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
    Uri Guttman, Mar 5, 2010
    #4
  5. with <> Uri Guttman wrote:
    >>>>>> "FS" == Frank Seitz <> writes:

    *SKIP*
    > FS> No, exists() checks array elements, too. See perdoc -f exists.


    And that entry is somewhat strange (underdeveloped?).

    *SKIP*
    > exists was changed to support arrays because of pseudohashes which now
    > are obsolete and removed from perl. maybe they should remove the array
    > side of exists too.


    I doubt that would ever happen ('breaking old code' spell). Although:

    % perl -wle '
    $x[25] = "";
    print "a$x[4]a" if exists $x[4];
    print "b$x[4]b" if defined $x[4];
    print "c$x[4]c" if $x[4];
    print "d$x[4]d"
    __END__
    '
    Use of uninitialized value $x[4] in concatenation (.) or string at -e line 6.
    dd

    Me smells XY-problem.

    --
    Torvalds' goal for Linux is very simple: World Domination
    Stallman's goal for GNU is even simpler: Freedom
    Eric Pozharski, Mar 5, 2010
    #5
  6. Frank Seitz Guest

    Uri Guttman wrote:
    >>>>>> "FS" == Frank Seitz <> writes:

    >
    > FS> Uri Guttman wrote:
    > >>>>>>> "j" == jidanni <> writes:
    > >>

    > j> How can I write
    > j> print $F[4] if exists $F[4];
    > j> even simpler?
    > j> print if exists for $F[4];
    > j> print if exists $_ for $F[4];
    > j> don't work.
    > >>
    > >> well, exists is for checking if a key exists in a hash. you don't have
    > >> any hashes there so of course it won't work.

    >
    > FS> No, exists() checks array elements, too. See perdoc -f exists.
    >
    > even so, it is a useless concept IMO.


    This is a completely different point.

    > array elements can be never
    > allocated or filled with undef and there is little reason to know the
    > difference. this is unlike knowing if a key exists regardless of its
    > value being set with undef or never being set. exists was changed to
    > support arrays because of pseudohashes which now are obsolete and
    > removed from perl. maybe they should remove the array side of exists
    > too.


    Here is a simple use case:

    my @a;
    $a[1] = 4711;
    $a[4] = 4712;

    for (my $i = 0; $i < @a; $i++) {
    printf "%d %s\n",$i,exists $a[$i]? 'filled': 'empty';
    }
    __END__
    0 empty
    1 filled
    2 empty
    3 empty
    4 filled

    Frank
    --
    Dipl.-Inform. Frank Seitz
    Anwendungen für Ihr Internet und Intranet
    Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

    Blog: http://www.fseitz.de/blog
    XING-Profil: http://www.xing.com/profile/Frank_Seitz2
    Frank Seitz, Mar 5, 2010
    #6
  7. On 04/03/2010 19:46, wrote:
    > How can I write
    > print $F[4] if exists $F[4];
    > even simpler?
    > print if exists for $F[4];
    > print if exists $_ for $F[4];
    > don't work.


    print $F[4];

    As in
    perl -e '$F[2]=2; $F[4]=4; for $i (1..5) {print $F[$i];}'
    24


    --
    RGB
    RedGrittyBrick, Mar 5, 2010
    #7
  8. Frank Seitz Guest

    Ben Morrow wrote:
    > Quoth Frank Seitz <>:
    >>
    >> my @a;
    >> $a[1] = 4711;
    >> $a[4] = 4712;
    >>
    >> for (my $i = 0; $i < @a; $i++) {
    >> printf "%d %s\n",$i,exists $a[$i]? 'filled': 'empty';

    >
    > WRONG. You mean 'defined'. Whether an element responds to 'exists' or
    > not depends on whether memory has been allocated to hold that element
    > yet, which is not generally something you can predict.


    In my understanding an array element "exists", when I assigned a
    value to it, otherwise not.

    my @a;
    $a[1] = 4711;
    $a[3] = undef;
    $a[4] = 4712;

    print "exists:\n";
    for (my $i = 0; $i < @a; $i++) {
    printf " %d %s\n",$i,exists $a[$i]? 'filled': 'empty';
    }
    print "defined:\n";
    for (my $i = 0; $i < @a; $i++) {
    printf " %d %s\n",$i,defined $a[$i]? 'filled': 'empty';
    }
    __END__
    exists:
    0 empty
    1 filled
    2 empty
    3 filled
    4 filled
    defined:
    0 empty
    1 filled
    2 empty
    3 empty
    4 filled

    I get what I expect. Where is the problem?

    Frank
    --
    Dipl.-Inform. Frank Seitz
    Anwendungen für Ihr Internet und Intranet
    Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

    Blog: http://www.fseitz.de/blog
    XING-Profil: http://www.xing.com/profile/Frank_Seitz2
    Frank Seitz, Mar 5, 2010
    #8
  9. Guest

    On Fri, 05 Mar 2010 12:59:29 +0100, Frank Seitz <> wrote:

    >Ben Morrow wrote:
    >> Quoth Frank Seitz <>:
    >>>
    >>> my @a;
    >>> $a[1] = 4711;
    >>> $a[4] = 4712;
    >>>
    >>> for (my $i = 0; $i < @a; $i++) {
    >>> printf "%d %s\n",$i,exists $a[$i]? 'filled': 'empty';

    >>
    >> WRONG. You mean 'defined'. Whether an element responds to 'exists' or
    >> not depends on whether memory has been allocated to hold that element
    >> yet, which is not generally something you can predict.

    >
    >In my understanding an array element "exists", when I assigned a
    >value to it, otherwise not.
    >

    Yes, exists() is more the an elements memory state: initialized or not.
    Defined'nes is the state of the elements value. And it can be possible
    that it is not defined, whether it exists or not.

    For arrays, existence is a test to determine if it has ever been touched
    as opposed to defined'nes when acting on its value.

    People think exists is just a test for hash keys, but it is very usefull
    when randomly indexing an array and perhaps it needs to get the air
    taken out of it, or something else distinguishing between initialized
    and defined.

    -sln
    , Mar 5, 2010
    #9
  10. Jim Gibson Guest

    In article <>, Frank Seitz
    <> wrote:

    > Ben Morrow wrote:
    > > Quoth Frank Seitz <>:
    > >>


    > > WRONG. You mean 'defined'. Whether an element responds to 'exists' or
    > > not depends on whether memory has been allocated to hold that element
    > > yet, which is not generally something you can predict.

    >
    > In my understanding an array element "exists", when I assigned a
    > value to it, otherwise not.
    >
    > my @a;
    > $a[1] = 4711;
    > $a[3] = undef;
    > $a[4] = 4712;
    >
    > print "exists:\n";
    > for (my $i = 0; $i < @a; $i++) {
    > printf " %d %s\n",$i,exists $a[$i]? 'filled': 'empty';
    > }
    > print "defined:\n";
    > for (my $i = 0; $i < @a; $i++) {
    > printf " %d %s\n",$i,defined $a[$i]? 'filled': 'empty';
    > }
    > __END__
    > exists:
    > 0 empty
    > 1 filled
    > 2 empty
    > 3 filled
    > 4 filled
    > defined:
    > 0 empty
    > 1 filled
    > 2 empty
    > 3 empty
    > 4 filled
    >
    > I get what I expect. Where is the problem?


    One problem would be that your expectations might differ from those of
    others, including mine. In your scenario, I would expect that, since
    the normal meaning of "array" is a contiguous set of members, that
    $a[0] and $a[2] would 'exist', since an array of length 5 needs to be
    allocated to hold $a[4], and $a[5] would not 'exist'. However, the
    exists function does not yield what I would expect:

    #!/usr/local/bin/perl

    use strict;
    use warnings;

    my @a;
    $a[1] = 1;
    $a[3] = undef;
    $a[4] = 4;

    for( my $i = 0; $i <= 5 ; $i++ ) {
    printf " %d %s\n", $i,
    ( $a[$i] ? 'filled' :
    ( defined $a[$i] ? 'defined' :
    ( exists $a[$i] ? 'exists':
    'non-existent' )));
    }

    _OUTPUT_

    0 non-existent
    1 filled
    2 non-existent
    3 exists
    4 filled
    5 non-existent

    I would have expected 'exists' for elements 0 and 2 and 'non-existent'
    only for 5.

    --
    Jim Gibson
    Jim Gibson, Mar 5, 2010
    #10
  11. Uri Guttman Guest

    >>>>> "JG" == Jim Gibson <> writes:

    JG> my @a;
    JG> $a[1] = 1;
    JG> $a[3] = undef;
    JG> $a[4] = 4;

    JG> for( my $i = 0; $i <= 5 ; $i++ ) {
    JG> printf " %d %s\n", $i,
    JG> ( $a[$i] ? 'filled' :

    0 would fail that and be defined but not filled. i would print all three
    possible states for each entry to really get the picture.

    JG> ( defined $a[$i] ? 'defined' :
    JG> ( exists $a[$i] ? 'exists':
    JG> 'non-existent' )));
    JG> }

    JG> _OUTPUT_

    JG> 0 non-existent
    JG> 1 filled
    JG> 2 non-existent
    JG> 3 exists
    JG> 4 filled
    JG> 5 non-existent

    JG> I would have expected 'exists' for elements 0 and 2 and 'non-existent'
    JG> only for 5.

    remember, exists tests arrays for where any allocation occured. this
    makes sense in some way. preallocating an array only allocates the
    slots, not the SV's that go into them. even assigning undef to a slot
    allocated storage for the SV. so defined will pass on an empty slot OR a
    slot assigned undef. only exists will tell if the slot was ever assigned
    to.


    my @a;
    $a[1] = 0;
    $a[3] = undef;
    $a[4] = 4;

    foreach my $i ( 0 .. $#a ) {
    print "$i: ", exists $a[$i] ? 'exists ' : '',
    defined $a[$i] ? 'defined ' : '',
    $a[$i] ? 'true' : '',
    "\n" ;
    }


    0:
    1: exists defined
    2:
    3: exists
    4: exists defined true

    note that [3] exists but isn't defined. it was allocated with an SV
    holding undef. [0] and [2] were never allocated so they don't even
    exist.

    now for the news that keys will work on arrays in 5.12. will it just
    create a list of the full indices? or only those indices that exist?
    also will each() now work on arrays? that will solve the age old (mostly
    newbie) request to get the index AND value from iterating over a
    list. p6 solves this with the .kv method/accessor which returns an
    index/value pair. each() would be similar to this in returning the next
    index/value pair as it does for hashes. something like this would be
    cool:

    while( my( $i, $val ) = each( @array ) ) {

    of course you better not modify the array length during this.
    maybe changing values would be allowed ($val should be an alias if
    possible to the element).

    uri

    --
    Uri Guttman ------ -------- http://www.sysarch.com --
    ----- Perl Code Review , Architecture, Development, Training, Support ------
    --------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
    Uri Guttman, Mar 5, 2010
    #11
  12. Guest

    On Fri, 05 Mar 2010 09:51:51 -0800, Jim Gibson <> wrote:

    >One problem would be that your expectations might differ from those of
    >others, including mine. In your scenario, I would expect that, since
    >the normal meaning of "array" is a contiguous set of members, that
    >$a[0] and $a[2] would 'exist', since an array of length 5 needs to be
    >allocated to hold $a[4], and $a[5] would not 'exist'. However, the
    >exists function does not yield what I would expect:
    >
    >#!/usr/local/bin/perl
    >
    >use strict;
    >use warnings;
    >
    >my @a;
    >$a[1] = 1;
    >$a[3] = undef;
    >$a[4] = 4;
    >
    >for( my $i = 0; $i <= 5 ; $i++ ) {
    > printf " %d %s\n", $i,
    > ( $a[$i] ? 'filled' :
    > ( defined $a[$i] ? 'defined' :
    > ( exists $a[$i] ? 'exists':
    > 'non-existent' )));
    >}
    >
    >_OUTPUT_
    >
    > 0 non-existent
    > 1 filled
    > 2 non-existent
    > 3 exists
    > 4 filled
    > 5 non-existent
    >
    >I would have expected 'exists' for elements 0 and 2 and 'non-existent'
    >only for 5.


    When you "initialize" an element, either hash or array, it goes into
    existence, not before.
    Even though you can do
    @array;
    $array[100] = undef;
    elements 0-99 are not initialized. However, the size of the array
    springs up to 101 elements, of which only element 101 is initialized.

    Hash's aren't based on continuous numeric indexes so the phrase
    "exists" is more appropriate to hash's than arrays.

    For arrays, the need to know if elements have been initialized, does have
    its place separate from defined, and therefore should be thought of as
    value initialization.

    Hash and array elements don't exist until they are initialized.

    I believe the below statement to be true (but can't say for sure):
    The actual @array is just a header that maintains slot information
    (pointers) for elements as they are "initialized", when the actual
    memory allocation for the data occurs.

    So, think exists for hashes, initialized for arrays.

    -sln
    , Mar 5, 2010
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Stan Goodman

    Even older fart, even newer newbie

    Stan Goodman, Jul 3, 2003, in forum: Java
    Replies:
    11
    Views:
    676
    Stan Goodman
    Jul 4, 2003
  2. could ildg
    Replies:
    0
    Views:
    454
    could ildg
    Jul 1, 2005
  3. Jeff Epler
    Replies:
    0
    Views:
    391
    Jeff Epler
    Jul 1, 2005
  4. could ildg
    Replies:
    0
    Views:
    489
    could ildg
    Jul 2, 2005
  5. Stef Mientki
    Replies:
    2
    Views:
    263
    Stef Mientki
    Nov 23, 2008
Loading...

Share This Page