kindergarten array vs. for question

Discussion in 'Perl Misc' started by Dan Jacobson, Dec 6, 2004.

  1. Dan Jacobson

    Dan Jacobson Guest

    my @a=(1,2,3); my @b=(4,5,6);
    for((((@a))),(((@b)))){ #What do I have to do to this line to make
    print "new array\n"; #this line get printed only twice, not six times?
    for($_){
    print "element $_\n"}}
    Dan Jacobson, Dec 6, 2004
    #1
    1. Advertising

  2. Dan Jacobson <> writes:
    > my @a=(1,2,3); my @b=(4,5,6);
    > for((((@a))),(((@b)))){ #What do I have to do to this line to make


    Yikes! You need a quick trip to 'perldoc perldata'. Do not pass go,
    do not collect $200. I'm not trying to make you feel bad here, but
    this is very basic stuff. If you didn't read this in perldata, you
    probably need to sit down and read that manpage, and probably at least
    skim perltoc as well.

    A short excerpt from perldata:

    LISTs do automatic interpolation of sublists. That is, when a
    LIST is evaluated, each element of the list is evaluated in
    list context, and the resulting list value is interpolated into
    LIST just as if each individual element were a member of LIST.

    So, what you're iterating over is the list (((@a))),(((@b))), which is
    equivalent to (@a),(@b), which is equivalent to @a,@b, which is in
    turn reduced to a list containing all the elements of @a followed by
    all the elements of @b.

    As a stylistic aside, if I ever find myself using $_ explicitly in a
    loop, that's usually a sign to me that I need to be using an explicit
    name for the variable. In your case, I might write it:

    for my $element (@a,@b) {
    ....
    }

    And then use $element where you have $_. This won't work in EVERY
    case, but it does work 9 times out of 10.

    > print "new array\n"; #this line get printed only twice, not six times?
    > for($_){
    > print "element $_\n"}}


    Also, this is kinda ugly from a personal POV: it doesn't match any
    standard indenting style I'm familiar with, and it makes it harder to
    find the close bracket for the outer for by hiding it at the end of
    the inner for. And even that one might be missed on a cursory
    reading.

    Anyway, to answer your question, the "right" answer depends on why you
    want to know. If you want to count how many arrays you put in the top
    of the for loop, well, that's a bit odd, since you're specifying them
    explicitly. You probably want to iterate over references to the
    arrays, except then you lose the name of the array when you do so (not
    sure if that would be a problem or not).

    That might look like:

    for my $array_ref (\@a, \@b) {
    print "new array, ref value: [$ref]";
    }

    read perlretoot for more info on references in Perl. Also perlref.

    -=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, Dec 6, 2004
    #2
    1. Advertising

  3. Dan Jacobson

    Andrew Hamm Guest

    Dan Jacobson wrote:
    > my @a=(1,2,3); my @b=(4,5,6);
    > for((((@a))),(((@b)))){
    > #What do I have to do to this line to make
    > #this line get printed only twice, not six times?
    > print "new array\n";
    > for($_){
    > print "element $_\n"
    > }
    > }


    I see what you are trying to achieve (I think) and you will need to use
    references. The answer will be more complicated than you might expect!

    my @a = (1, 2, 3);
    my @b = (4, 5, 6);

    for(\@a, \@b) {
    print "new array\n";
    for(@$_) {
    print " element $_\n";
    }
    }

    No matter how many ( ) you wrap around a list, it is flattened down to a
    single-level list in Perl. So your attempt to make

    (((@a))),(((@b)))

    is the same as

    @a, @b

    Which is given to "for"; and guess what, "for" takes a list which is
    logically (and syntactically) wrapped in another ( ) so you get

    (@a, @b)

    which ultimately yields

    (1, 2, 3, 4, 5, 6)

    my solution takes the "address of" @a and @b by applying the \ operator.
    NOTE: Perl is higherlevel than a machine-oriented language like C or C++,
    so calling it an "address of" is not strictly true. There is more in a
    Perl "reference" than just a simple address. But for practical purposes
    it's very simple to informally consider it to be an address if that helps
    you to understand.

    Now, my outside for loop gets two values: the address of @a and the
    address of @b. This gives you the two prints of the line you want.

    The next problem is getting to the values "pointed to" or referred to by
    the reference. If $X contains a reference, then "pretend" or treat it as a
    unit which is a variable name:

    $thingy # a scalar variable
    @listy # an array variable
    $$rthingy # dereference a reference to a scalar variable
    @$rlisty # dereference a reference to an array variable

    for total safety while you are learning, it's safer to write

    ${$rthingy} @{$rlisty}

    because the { } puts a very clear boundary around the reference, and
    really makes it clear what goes with what.

    There's no point in me going any further here because the subject is
    wellcovered in the doco. See

    perldoc perlreftut

    and

    perldoc perlref

    and study well. References are very powerful, a bit mind-bending, and are
    central to the Perl way of making complex data structures.
    Andrew Hamm, Dec 6, 2004
    #3
    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. Joseph Turian
    Replies:
    11
    Views:
    498
    Joseph Turian
    Jan 19, 2005
  2. Fabio
    Replies:
    0
    Views:
    298
    Fabio
    Nov 5, 2008
  3. Mara Guida

    const and array of array (of array ...)

    Mara Guida, Sep 2, 2009, in forum: C Programming
    Replies:
    3
    Views:
    465
    David RF
    Sep 3, 2009
  4. Tom
    Replies:
    3
    Views:
    187
    salsablr
    Dec 20, 2004
  5. Tuan  Bui
    Replies:
    14
    Views:
    452
    it_says_BALLS_on_your forehead
    Jul 29, 2005
Loading...

Share This Page