References to an array in a foreach

Discussion in 'Perl Misc' started by David K. Wall, Oct 14, 2004.

  1. David Green <> wrote:

    > I have a problem with references to arrays and would be grateful
    > if someone could give me some help or alternatively propose a
    > better method to use in solving my problem.
    >
    > Take for example the following code:
    >
    > my @animals = ( "\@reptiles", "\@mammals", "\@birds" );


    @animals now contains the strings '@reptiles', '@mammals', and
    '@birds', but no references.

    > my @birds = ( "owl", "swan", "pelican" );
    > my @reptiles = ( "crocodile", "gecko" );
    > my @mammals = ( "fox", "cheeta", "man" );


    It's probably a good thing that @animals only contains strings,
    because the arrays you meant to reference didn't exist yet.

    > What I think I've done here is set up an array called @animals
    > which contains references to the three arrays @birds, @reptiles
    > and @mammals.


    Nope, sorry.


    > What I would like to do is use a pair of <foreach> loops to read
    > each value from the three arrays in sequence (exact order
    > unimportant).


    I'd suggest reading perllol.


    > Defining two worker variables:
    > my $thiskey, $thatkey;
    >
    > foreach $thatkey (@animals) {
    >
    > foreach $thiskey (@$thatkey) { # Here I try to dereference
    > the array print $thiskey . ","; # and presumably
    > fail?
    > };
    >};
    >
    > I would expect the output:
    > "crocodile,gecko,fox,cheeta,man,owl,swan,pelican", but instead get
    > no output. To even get this code to run I have to remove <use
    > strict> else Perl refuses to run the code.


    Don't do that. Perl knows more about it than you do at the moment.
    :)

    I'm not the best explainer (or at least I'm too lazy to type a lot of
    stuff), so how about trying this:

    use strict;
    use warnings;

    my @birds = qw(owl swan pelican);
    my @reptiles = qw(crocodile gecko);
    my @mammals = qw(fox cheeta man);

    my @animals = \( @reptiles, @mammals, @birds );

    print join ', ', map { @$_ } @animals;
     
    David K. Wall, Oct 14, 2004
    #1
    1. Advertising

  2. David K. Wall

    David Green Guest

    Hey all,

    I have a problem with references to arrays and would be grateful if
    someone could give me some help or alternatively propose a better method
    to use in solving my problem.

    Take for example the following code:

    my @animals = ( "\@reptiles", "\@mammals", "\@birds" );
    my @birds = ( "owl", "swan", "pelican" );
    my @reptiles = ( "crocodile", "gecko" );
    my @mammals = ( "fox", "cheeta", "man" );

    What I think I've done here is set up an array called @animals which
    contains references to the three arrays @birds, @reptiles and @mammals.

    What I would like to do is use a pair of <foreach> loops to read each
    value from the three arrays in sequence (exact order unimportant).

    Defining two worker variables:
    my $thiskey, $thatkey;

    foreach $thatkey (@animals) {

    foreach $thiskey (@$thatkey) { # Here I try to dereference the array
    print $thiskey . ","; # and presumably fail?
    };
    };

    I would expect the output:
    "crocodile,gecko,fox,cheeta,man,owl,swan,pelican", but instead get no
    output. To even get this code to run I have to remove <use strict> else
    Perl refuses to run the code.

    The ultimate aim in this seemingly strange setup is to allow an unlimited
    number of members to @animals and an unlimited number of animals in each
    different 'kingdom'. In reality i'm actually using such a system to manage
    a lot of metadata for a package manager I'm working on.

    How can I get the output I'm after (preferably retaining strict refs) or
    alternatively provide data organised in such a way. If any more
    information helps or I'm unclear please let me know,

    Thanks,
    Dave

    --
    David Green ()
    Hands up for human rights!
    http://www.amnesty.org
     
    David Green, Oct 14, 2004
    #2
    1. Advertising

  3. David Green <> wrote in
    news:p:

    > Hey all,
    >
    > I have a problem with references to arrays and would be grateful if
    > someone could give me some help or alternatively propose a better
    > method to use in solving my problem.
    >
    > Take for example the following code:
    >
    > my @animals = ( "\@reptiles", "\@mammals", "\@birds" );
    > my @birds = ( "owl", "swan", "pelican" );
    > my @reptiles = ( "crocodile", "gecko" );
    > my @mammals = ( "fox", "cheeta", "man" );
    >
    > What I think I've done here is set up an array called @animals which
    > contains references to the three arrays @birds, @reptiles and
    > @mammals.


    That is absolutely one hundred percent wrong. Where have you every seen
    such syntax? You can't make stuff up and expect it to work you know.

    What you have done instead is to create an array called @animals
    containing the strings '@reptiles', '@mammals', and '@birds'.

    > What I would like to do is use a pair of <foreach> loops to read each
    > value from the three arrays in sequence (exact order unimportant).
    >
    > Defining two worker variables:
    > my $thiskey, $thatkey;


    Always declare your variables in the smallest possible scope. Don't give
    them misleading names (such as $key).

    > foreach $thatkey (@animals) {
    >
    > foreach $thiskey (@$thatkey) { # Here I try to dereference the
    > array print $thiskey . ","; # and presumably fail?


    I am speechless.

    You can't make stuff up like this.

    > I would expect the output:
    > "crocodile,gecko,fox,cheeta,man,owl,swan,pelican", but instead get no
    > output.


    Why would you expect that?

    > To even get this code to run I have to remove <use strict>
    > else Perl refuses to run the code.


    It is a BAD SIGN when you have to remove use strict to get your code to
    run. Why don't you instead read the message you get? WHile you are at it,
    you could also add a simple use diagnostics to get a more detailed
    description.

    > The ultimate aim in this seemingly strange setup is to allow an
    > unlimited number of members to @animals and an unlimited number of
    > animals in each different 'kingdom'. In reality i'm actually using
    > such a system to manage a lot of metadata for a package manager I'm
    > working on.


    Please let us know what it is so we know never ever under any
    circumstances to use it.

    > If any more information helps or I'm unclear please let me know,


    You are very clear. You refuse to read.

    Have you looked at perldoc perlref?

    Sinan.
     
    A. Sinan Unur, Oct 14, 2004
    #3
  4. David Green wrote:

    > Hey all,
    >
    > I have a problem with references to arrays and would be grateful if
    > someone could give me some help or alternatively propose a better method
    > to use in solving my problem.
    >
    > Take for example the following code:
    >
    > my @animals = ( "\@reptiles", "\@mammals", "\@birds" );
    > my @birds = ( "owl", "swan", "pelican" );
    > my @reptiles = ( "crocodile", "gecko" );
    > my @mammals = ( "fox", "cheeta", "man" );
    >
    > What I think I've done here is set up an array called @animals which
    > contains references to the three arrays @birds, @reptiles and @mammals.


    No you have not. @animals is an array of strinf. If you want it to be
    an array of references you'd need to remove the quotes from the first line.

    >
    > What I would like to do is use a pair of <foreach> loops to read each
    > value from the three arrays in sequence (exact order unimportant).
    >
    > Defining two worker variables:
    > my $thiskey, $thatkey;


    Firstly you mean "declaring" not "defining". Secondly you are suffering
    from the unfortuante affliction of "premature declaration". You should
    always declare all variables in the smallest applicable scope unless you
    have a positive reason to do otherwise. In the case of for-loop
    iterator variables the correct place to delare these variables is in the
    for statement itself.

    > foreach $thatkey (@animals) {
    >
    > foreach $thiskey (@$thatkey) { # Here I try to dereference the array
    > print $thiskey . ","; # and presumably fail?
    > };
    > };


    If @animals where an array of array references that code would would
    work just fine.

    >
    > I would expect the output:
    > "crocodile,gecko,fox,cheeta,man,owl,swan,pelican", but instead get no
    > output. To even get this code to run I have to remove <use strict> else
    > Perl refuses to run the code.


    If your smoke alarm is sounding, put out the fire, do not remove the
    batteries. Did you actually read the error Perl gave you? It told you
    what was wrong. It told you that you were using a string where you
    needed a reference.
     
    Brian McCauley, Oct 14, 2004
    #4
  5. On Thu, 14 Oct 2004, David Green <> wrote:

    > my @animals = ( "\@reptiles", "\@mammals", "\@birds" );


    Two problems:
    The format "\@array" gives you the same thing as '@array', in other
    words, a literal ampersand. What you probably meant to do is:

    my @animals = ( \@reptiles, \@mammals, \@birds );

    The second problem here is that you are referencing arrays that don't
    exist yet. If you had started out with:

    use warnings;
    use strict;

    then Perl would have told you some of the problems (once you fixed the
    problem with the quotes, anyway).

    > my $thiskey, $thatkey;


    This should probably be:

    my ($thiskey, $thatkey); # [1]

    or better yet, move the my into the foreach statements:

    foreach my $thatkey (@animals) {
    foreach my $thiskey (@$thatkey) {
    print $thiskey . ",";
    };
    };


    ### Here it is with the errors fixed:

    use warnings;
    use strict;

    my @birds = ( "owl", "swan", "pelican" );
    my @reptiles = ( "crocodile", "gecko" );
    my @mammals = ( "fox", "cheeta", "man" );
    my @animals = ( \@reptiles, \@mammals, \@birds );

    foreach my $thatkey (@animals) {
    foreach my $thiskey (@$thatkey) {
    print $thiskey . ",";
    };
    };

    ###

    [1] from perldoc -f my: If more than one value is listed, the list must
    be placed in parentheses.

    --
    Todd de Gruyl
     
    Todd de Gruyl, Oct 14, 2004
    #5
  6. "A. Sinan Unur" <> wrote in
    news:Xns9582A2C548DB0asu1cornelledu@132.236.56.8:

    > David Green <> wrote in
    > news:p:


    >> foreach $thatkey (@animals) {
    >>
    >> foreach $thiskey (@$thatkey) { # Here I try to dereference the
    >> array print $thiskey . ","; # and presumably fail?

    >
    > I am speechless.
    >
    > You can't make stuff up like this.


    I sincerely apologize for this remark. I do not know where the word 'array'
    came from in my copy. Must have been some kind of inadvertent paste on my
    part.

    To make up for my mistake, here is an answer to your other question:

    > The ultimate aim in this seemingly strange setup is to allow an
    > unlimited number of members to @animals and an unlimited number of
    > animals in each different 'kingdom'. In reality i'm actually using
    > such a system to manage a lot of metadata for a package manager I'm
    > working on.


    What you really want to use is a hash for animals, rather than an array. It
    will make your life easier.

    That is:

    #! perl

    use strict;
    use warnings;

    my %animals = (
    birds => [ qw(owl swan pelican) ],
    reptiles => [ qw(crocodile gecko) ],
    mammals => [ qw(fox cheeta man) ],
    );

    # add a species to a group

    push @{ $animals{birds} }, 'sparrow';

    for my $species (keys %animals) {
    print ucfirst $species, ": ";
    print join(', ', @{ $animals{$species} }), "\n";
    }

    __END__

    Hope this helps.

    Sinan.
     
    A. Sinan Unur, Oct 15, 2004
    #6
  7. David Green <> wrote in
    news:p:

    >> You are very clear. You refuse to read.
    >>
    >> Have you looked at perldoc perlref?
    >>

    > Yes and yes. Notice how others were kind enough to provide a bit of a
    > description as to where to look. It's fine to tell people to RTFM if
    > you tell them which manual you would like them to read - I have at
    > least a thousand pages of documentation packaged with my installation
    > to read, let alone other resources.


    I did tell you exactly where to look.

    perlref, that is, "Perl references and nested data structures", ought to be
    the first place you look at when you are trying to figure out how to take a
    reference to something.

    Oh, by the way, perldoc perltoc will give you a table of contents so you
    don't have to guess.

    Sinan.
     
    A. Sinan Unur, Oct 15, 2004
    #7
  8. David K. Wall

    David Green Guest

    On Thu, 14 Oct 2004 20:00:03 +0000, A. Sinan Unur spoke:

    > David Green <> wrote in
    > news:p:
    >> Take for example the following code:
    >>
    >> my @animals = ( "\@reptiles", "\@mammals", "\@birds" );
    >> my @birds = ( "owl", "swan", "pelican" );
    >> my @reptiles = ( "crocodile", "gecko" );
    >> my @mammals = ( "fox", "cheeta", "man" );
    >>
    >> What I think I've done here is set up an array called @animals which
    >> contains references to the three arrays @birds, @reptiles and
    >> @mammals.

    >
    > That is absolutely one hundred percent wrong. Where have you every seen
    > such syntax? You can't make stuff up and expect it to work you know.
    >

    It's an adaptation (errors my own) of some code I found online. I hope
    that by trialing new ideas I might improve my coding skills. Is that not
    how most things, especially new languages are learnt?

    > Always declare your variables in the smallest possible scope. Don't give
    > them misleading names (such as $key).


    Provided as an illustration only, but even so I would question as a
    general idea in programming that the problem of having such a named
    variable that's going to fall out of scope *very* soon and only iterate
    over a set of values is not terribly significant.

    >> To even get this code to run I have to remove <use strict> else Perl
    >> refuses to run the code.

    >
    > It is a BAD SIGN when you have to remove use strict to get your code to
    > run. Why don't you instead read the message you get?


    I did read it (somewhat obviously) and whilst I understood something was
    wrong and to some extent why I did not have the knowledge to fix it. Of
    course it's a bad sign - why did I run with use strict to start with? It's
    an observation that it works without- read my post and you'll see how I
    want to run without having to remove it!
    >


    > You are very clear. You refuse to read.
    >
    > Have you looked at perldoc perlref?
    >

    Yes and yes. Notice how others were kind enough to provide a bit of a
    description as to where to look. It's fine to tell people to RTFM if you
    tell them which manual you would like them to read - I have at least a
    thousand pages of documentation packaged with my installation to read, let
    alone other resources.

    I would be interested in your replies but please some actual content this
    time rather than a series of insults and rebuttal that offers no
    assistance, such posts are a rather a waste of everyones bandwidth.

    David
    > Sinan.


    --
    David Green ()
    Hands up for human rights!
    http://www.amnesty.org
     
    David Green, Oct 15, 2004
    #8
  9. David K. Wall

    David Green Guest

    On Thu, 14 Oct 2004 15:14:30 -0500, Todd de Gruyl rambled:

    > ### Here it is with the errors fixed:
    >
    > use warnings;
    > use strict;
    >
    > my @birds = ( "owl", "swan", "pelican" );

    <snip>
    Thanks kindly for your help, I'll try this code as well as the
    perllol documentation recommended earlier. I think I dropped the
    parentheses in a hurry typing - didn't want to copy and paste a lot of
    of superfluos code so typed out fresh what I had in mind, appologies.

    Regards,
    Dave
     
    David Green, Oct 15, 2004
    #9
  10. On 2004-10-14, A. Sinan Unur <> wrote:
    >
    > What you really want to use is a hash for animals


    Really, this sounds like something the SPCA might come after you for...
    :)

    dha

    --
    David H. Adler - <> - http://www.panix.com/~dha/
    And finally, it appears that Schwern, Michael is an Alien Drag Queen
    - Leon Brocard, London.pm List Weekly Summary 2001-03-19
    (This has *something* to do with http://us.imdb.com/Title?0103645)
     
    David H. Adler, Oct 15, 2004
    #10
  11. David H. Adler wrote:
    > On 2004-10-14, A. Sinan Unur <> wrote:
    >
    >>What you really want to use is a hash for animals

    >
    >
    > Really, this sounds like something the SPCA might come after you for...
    > :)


    Or PETA


    John
    --
    use Perl;
    program
    fulfillment
     
    John W. Krahn, Oct 15, 2004
    #11
  12. A. Sinan Unur <> wrote:
    > "A. Sinan Unur" <> wrote in
    > news:Xns9582A2C548DB0asu1cornelledu@132.236.56.8:
    >> David Green <> wrote in
    >> news:p:


    >>> foreach $thiskey (@$thatkey) { # Here I try to dereference the
    >>> array print $thiskey . ","; # and presumably fail?


    > I do not know where the word 'array'
    > came from in my copy.



    Looks like it came from word-wrap to me.


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Oct 15, 2004
    #12
  13. David Green <> wrote:

    > didn't want to copy and paste a lot of
    > of superfluos code



    So then, only copy and paste the pertinent code.


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Oct 15, 2004
    #13
  14. Tad McClellan <> wrote in
    news::

    > A. Sinan Unur <> wrote:
    >> "A. Sinan Unur" <> wrote in
    >> news:Xns9582A2C548DB0asu1cornelledu@132.236.56.8:
    >>> David Green <> wrote in
    >>> news:p:

    >
    >>>> foreach $thiskey (@$thatkey) { # Here I try to dereference the
    >>>> array print $thiskey . ","; # and presumably fail?

    >
    >> I do not know where the word 'array'
    >> came from in my copy.

    >
    >
    > Looks like it came from word-wrap to me.


    Once again, you are right.

    Comments in the right margin do have a tendency to wrap around. One ought
    to be able to copy and paste the posted code without too much effort. The
    commenting style above does not help with that.

    Sinan.
     
    A. Sinan Unur, Oct 15, 2004
    #14
  15. David K. Wall

    Eric Bohlman Guest

    "David H. Adler" <> wrote in
    news::

    > On 2004-10-14, A. Sinan Unur <> wrote:
    >>
    >> What you really want to use is a hash for animals

    >
    > Really, this sounds like something the SPCA might come after you for...
    >:)


    I could see them objecting to a hash *of* animals, but what would worry
    them about a hash *for* animals? :)
     
    Eric Bohlman, Oct 19, 2004
    #15
    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. Tim Shoppa
    Replies:
    45
    Views:
    545
    Darren Dunham
    Dec 23, 2003
  2. Gavin Sherlock
    Replies:
    1
    Views:
    107
    Uri Guttman
    Dec 10, 2003
  3. Bill
    Replies:
    3
    Views:
    119
    Paul Lalli
    Jul 17, 2004
  4. Tomasz Chmielewski

    foreach - sorted array the way I want?

    Tomasz Chmielewski, Dec 10, 2009, in forum: Perl Misc
    Replies:
    3
    Views:
    181
    J├╝rgen Exner
    Dec 11, 2009
  5. divyajacob
    Replies:
    8
    Views:
    146
    Uri Guttman
    Jun 15, 2010
Loading...

Share This Page