Using undef as an array subscript

Discussion in 'Perl Misc' started by Yehuda Berlinger, Jul 1, 2003.

  1. This one is a surprise:

    @a = (0,undef);
    @b = (1,2);

    @c[@a] = @b;

    I was hoping to see $c[0] == '1', but I got '2'. Apparently, undef is
    converted to '0' when used as an array subscript. Is this documented
    anywhere, or is it something too obvious to document? I coudn't find
    it in the usual places.

    I was hoping to avoid doing a loop such as:

    @bb = @b;
    foreach $a (@a) {
    my $b = shift @bb;
    next unless defined $a;
    $c[$a] = $b;
    }

    Any thoughts?

    Yehuda
    Yehuda Berlinger, Jul 1, 2003
    #1
    1. Advertising

  2. Yehuda Berlinger

    Greg Bacon Guest

    In article <>,
    Yehuda Berlinger <> wrote:

    : This one is a surprise:
    :
    : @a = (0,undef);
    : @b = (1,2);
    :
    : @c[@a] = @b;
    :
    : I was hoping to see $c[0] == '1', but I got '2'. Apparently, undef is
    : converted to '0' when used as an array subscript. Is this documented
    : anywhere, or is it something too obvious to document? I coudn't find
    : it in the usual places.

    Well, it's defined in the perldiag manpage:

    Use of uninitialized value%s
    (W uninitialized) An undefined value was used as if it
    were already defined. It was interpreted as a "" or a
    0, but maybe it was a mistake. To suppress this
    warning assign a defined value to your variables.

    Certainly this is documented elsewhere, but a quick glance didn't bear
    fruit.

    : I was hoping to avoid doing a loop such as:
    :
    : @bb = @b;
    : foreach $a (@a) {
    : my $b = shift @bb;
    : next unless defined $a;
    : $c[$a] = $b;
    : }
    :
    : Any thoughts?

    Can we step up a level conceptually? What are you trying to do?

    Greg
    --
    . . . aggressors cannot wage total war without introducing socialism.
    -- Ludwig von Mises, *Interventionism: an Economic Analysis*
    Greg Bacon, Jul 1, 2003
    #2
    1. Advertising

  3. Yehuda Berlinger

    JS Bangs Guest

    Yehuda Berlinger sikyal:

    > This one is a surprise:
    >
    > @a = (0,undef);
    > @b = (1,2);
    >
    > @c[@a] = @b;
    >
    > I was hoping to see $c[0] == '1', but I got '2'. Apparently, undef is
    > converted to '0' when used as an array subscript. Is this documented
    > anywhere, or is it something too obvious to document? I coudn't find
    > it in the usual places.
    >
    > I was hoping to avoid doing a loop such as:
    >
    > @bb = @b;
    > foreach $a (@a) {
    > my $b = shift @bb;
    > next unless defined $a;
    > $c[$a] = $b;
    > }
    >
    > Any thoughts?


    Since your goal is apparently to use the contents of @a to define
    subscripts of @c, you could just filter the undefs out of @a first:

    @a = grep { defined($_) } @a;

    No messy loop, no undefs to mess up your subscripting. You could even put
    the whole thing inside the subscript definition for @c, if you don't mind
    being slightly obtuse:

    @c[grep { defined($_) } @a] = @b;


    Jesse S. Bangs
    http://students.washington.edu/jaspax/
    http://students.washington.edu/jaspax/blog

    Jesus asked them, "Who do you say that I am?"

    And they answered, "You are the eschatological manifestation of the ground
    of our being, the kerygma in which we find the ultimate meaning of our
    interpersonal relationship."

    And Jesus said, "What?"
    JS Bangs, Jul 1, 2003
    #3
  4. Yehuda Berlinger

    JS Bangs Guest

    Greg Bacon sikyal:

    > In article <>,
    > JS Bangs <> wrote:
    >
    > : @c[grep { defined($_) } @a] = @b;
    >
    > That doesn't throw away the corresponding elements of @b.


    ???? I don't understand what you mean by "throw away the corresponding
    elements of @b". Based on the original code we saw, the OP doesn't seem to
    want to alter @b at all, but only to make @c into a subset of @b. But
    perhaps I've missed something. Can the OP herself clarify?


    Jesse S. Bangs
    http://students.washington.edu/jaspax/
    http://students.washington.edu/jaspax/blog

    Jesus asked them, "Who do you say that I am?"

    And they answered, "You are the eschatological manifestation of the ground
    of our being, the kerygma in which we find the ultimate meaning of our
    interpersonal relationship."

    And Jesus said, "What?"
    JS Bangs, Jul 1, 2003
    #4
  5. Yehuda Berlinger

    Matija Papec Guest

    X-Ftn-To: Yehuda Berlinger

    (Yehuda Berlinger) wrote:
    > @a = (0,undef);
    > @b = (1,2);
    >
    > @c[@a] = @b;
    >
    >I was hoping to see $c[0] == '1', but I got '2'. Apparently, undef is
    >converted to '0' when used as an array subscript. Is this documented
    >anywhere, or is it something too obvious to document? I coudn't find
    >it in the usual places.
    >
    >I was hoping to avoid doing a loop such as:
    >
    > @bb = @b;
    > foreach $a (@a) {
    > my $b = shift @bb;
    > next unless defined $a;
    > $c[$a] = $b;
    > }
    >
    >Any thoughts?


    you could,
    $c[0] = $b[
    (grep defined $a[$_] && !$a[$_], 0..$#a)[-1]
    ];
    just after @c[@a] = @b;

    but after this, foreach looks very tempting ;)

    btw, why are you having undefs in @a in the first place?



    --
    Matija
    Matija Papec, Jul 1, 2003
    #5
  6. Yehuda Berlinger

    Matija Papec Guest

    X-Ftn-To: JS Bangs

    JS Bangs <> wrote:
    >> : @c[grep { defined($_) } @a] = @b;
    >>
    >> That doesn't throw away the corresponding elements of @b.

    >
    >???? I don't understand what you mean by "throw away the corresponding
    >elements of @b". Based on the original code we saw, the OP doesn't seem to
    >want to alter @b at all, but only to make @c into a subset of @b. But
    >perhaps I've missed something. Can the OP herself clarify?


    @a and @b, each have same number of elements, so when removing from @a, one
    should remove corresponding element from @b, so @c[@a] = @b could work as
    expected.



    --
    Matija
    Matija Papec, Jul 1, 2003
    #6
  7. JS Bangs <> writes:
    > ???? I don't understand what you mean by "throw away the corresponding
    > elements of @b".


    The OP's code always shifted off an entry from @b (well, from a copy
    of it named @bb) for every element of @a, even if that element was
    undefined. Your code assumes that

    scalar(@b) == scalar(grep { defined($_) } @a )

    which is not necessarily true.

    > Based on the original code we saw, the OP doesn't seem to
    > want to alter @b at all, but only to make @c into a subset of @b. But
    > perhaps I've missed something. Can the OP herself clarify?


    Based on the original code, the idea is that @c contains all the
    elements of $b for which the corresponding element in $a is defined.
    I think Greg's point was that you forgot that @b may contain elements
    that correspond to undefined elements in @a, and thus shouldn't be
    included.

    To the OP: You can adapt JS' code to not explicitly require a loop,
    but a loop is going to happen anyway, whether you make it explicit or
    not. I think you'll find that using the loop code is going to be more
    readable and maintainable than more arcane trickery.

    -=Eric
    --
    Come to think of it, there are already a million monkeys on a million
    typewriters, and Usenet is NOTHING like Shakespeare.
    -- Blair Houghton.
    Eric Schwartz, Jul 1, 2003
    #7
  8. Yehuda Berlinger

    Greg Bacon Guest

    In article <>,
    Yehuda Berlinger <> wrote:

    : [...]
    :
    : I was hoping to avoid doing a loop such as:
    :
    : @bb = @b;
    : foreach $a (@a) {
    : my $b = shift @bb;
    : next unless defined $a;
    : $c[$a] = $b;
    : }
    :
    : Any thoughts?

    You could do it this way:

    #! /usr/local/bin/perl

    use warnings;

    use Data::Dumper;

    sub zip {
    use strict;

    my @a = @{ $_[0] || [] };
    my @b = @{ $_[1] || [] };

    my @result;
    push @result => [shift @a, shift @b] while @a || @b;

    @result;
    }

    @a = (0, undef);
    @b = (1, 2);

    $c[ $_->[0] ] = $_->[1] for grep defined($_->[0]), zip \@a, \@b;
    print Dumper \@c;

    Don't do it that way, though; it has little value outside a puzzle or
    challenge. If we had a better idea of what you're trying to model,
    we might be able to offer better suggestions.

    Perl 6 will have parallel traversal, so you'll someday be able to

    for @a; @b -> $a; $b {
    @c[$a] = $b if defined $a;
    }

    Greg
    --
    When a true genius appears in this world, you may know him by this sign,
    that the dunces are all in confederacy against him.
    -- Jonathan Swift
    Greg Bacon, Jul 1, 2003
    #8
  9. Yehuda Berlinger

    Greg Bacon Guest

    In article <>,
    Greg Bacon <> wrote:

    : Perl 6 will have parallel traversal, so you'll someday be able to
    :
    : for @a; @b -> $a; $b {
    : @c[$a] = $b if defined $a;
    : }

    Sorry, no reference. The foreshadowing comes from Apocalypse 4,
    RFC 173. The URL is hideous, so visit

    http://makeashorterlink.com/?X6E411E15

    Greg
    --
    . . . but the twin deficits [trade and Federal] aren't just theoretical
    economic issues anymore. They're starting to end careers in Washington.
    Maybe deficits aren't all bad after all . . .
    -- Hans Sennholz, "Deficits Do Matter"
    Greg Bacon, Jul 1, 2003
    #9
    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. Tom Page
    Replies:
    4
    Views:
    461
    Victor Bazarov
    Feb 17, 2004
  2. Richard Delorme

    out of range array subscript

    Richard Delorme, May 3, 2004, in forum: C Programming
    Replies:
    5
    Views:
    476
    Chris Torek
    May 15, 2004
  3. Ivan
    Replies:
    16
    Views:
    641
    Pascal J. Bourguignon
    Jun 20, 2008
  4. David
    Replies:
    1
    Views:
    76
    J├╝rgen Exner
    Nov 11, 2004
  5. Tim McDaniel

    undef($foo) versus $foo = undef()?

    Tim McDaniel, Aug 19, 2009, in forum: Perl Misc
    Replies:
    6
    Views:
    141
    Peter J. Holzer
    Aug 19, 2009
Loading...

Share This Page