http://www.perlmonks.org?node_id=1033068

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

Hi Monks, Is below code legal? I am expecting the loop to run until all the variables of each array has been iterated. (Arrays are not the same size)
foreach my $file (@files, @files2, @files3) { do something }
Thanks for reading.

Replies are listed 'Best First'.
Re: Passing multiple arrays to foreach loop
by Athanasius (Archbishop) on May 11, 2013 at 02:17 UTC
Re: Passing multiple arrays to foreach loop
by toolic (Bishop) on May 11, 2013 at 01:09 UTC
    use warnings; use strict; my @f1 = qw(x y z); my @f2 = qw(a b); for (@f1, @f2) { print "$_\n"; } __END__ x y z a b
Re: Passing multiple arrays to foreach loop
by AnomalousMonk (Archbishop) on May 11, 2013 at 04:08 UTC

    The only situation in which you will get into trouble is if you include an honest-to-goodness list literal in your for-loop iteration list and then try to do some mutating operation on it.

    >perl -wMstrict -le "my @ra1 = qw(foo bar); my @ra2 = qw(does not get here); ;; for my $file (@ra1, 'zonk', @ra2) { $file .= '-appendage'; print qq{'$file'}; } " 'foo-appendage' 'bar-appendage' Modification of a read-only value attempted at -e line 1.
Re: Passing multiple arrays to foreach loop
by GrandFather (Saint) on May 11, 2013 at 09:43 UTC

    Did you try it? Did it work?

    It took me about a minute to write and run:

    #!/usr/bin/env perl use warnings; use strict; my @files1 = 1 .. 3; my @files2 = 4 .. 6; for my $file (@files1, @files2) { print "$file\n"; }

    which prints:

    1 2 3 4 5 6

    Actually the first three lines are boiler plate so I didn't actually write those as part of the test so really I only wrote two more lines than your sample code. If you'd have tried it yourself you'd have had a yes/no answer in about the time it took to write your question and probably about 1/5th the time it took for you to see the first answer.

    True laziness is hard work
      «...If you'd have tried it yourself you'd have had a yes/no answer in about the time it took to write your question and probably about 1/5th the time it took for you to see the first answer»

      Nothing but the truth. But perhaps this has something to do with that you are Cardinal and the OP is Novice ;-)

      Best regards, Karl

      «The Crux of the Biscuit is the Apostrophe»

        deshdaaz asked if this code legal or no. Who knows maybe this code works but considered as dirty hack, or considered deprecated.
      Yes Sir, I did try and it did work. However my actual code goes through more than thousand files and I was not certain if it actually completed all three arrays or not hence the question. Sorry for the trouble.
        From all the answers you got, the one from Athanasius was IMHO the best so far.

        It's elementary for Perl that @arrays and %hashes are flattened in list context, not only in the case of a foreach (LIST), but whenever the docs talk about "LIST" as parameter.

        from perldata#List value constructors

        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. Thus arrays and hashes lose their identity in a LIST--the list

        (@foo,@bar,&SomeSub,%glarch)

        contains all the elements of @foo followed by all the elements of @bar, followed by all the elements returned by the subroutine named SomeSub called in list context, followed by the key/value pairs of %glarch.

        for instance
        DB<105> @a=1..3 => (1, 2, 3) DB<106> @b=a..c => ("a", "b", "c") DB<107> @c=(@a,@b) => (1, 2, 3, "a", "b", "c")

        HTH! =)

        Cheers Rolf

        ( addicted to the Perl Programming Language)

        It was not "trouble", and actually not a bad question, but learning to write small test programs to check your understanding is a very useful art. The same art applies when the question grows beyond anything one can answer for oneself, but then the art morphs into being able to create a small focused test script that others can use as a test bed for understanding your issue and providing a solution.

        True laziness is hard work
Re: Passing multiple arrays to foreach loop
by Random_Walk (Prior) on May 11, 2013 at 07:48 UTC

    This will work and you will itterate a list containing each element from each array. If you should want to be able to tell which array is which then you can itterate references instead.

    use strict; use warnings; my @foo = qw(one two three); my @bar = qw(four five six); my @baz = qw(seven eight nine); my $i = 0; for my $array_ref (\@foo, \@bar, \@baz) { # pass references print "starting array: ".++$i."\n"; for (@$array_ref) { # de-reference print " array: $i val: $_\n"; } }

    Cheers,
    R.

    Pereant, qui ante nos nostra dixerunt!