Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Populating Arrays of Arrays

by dReKurCe (Scribe)
on Mar 03, 2005 at 19:06 UTC ( [id://436332]=perlquestion: print w/replies, xml ) Need Help??

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

Greetings Monks

This is a foray into 3 dimensional data structures. The aoa in question is at the end, I can't seem to sort out my references and dereferences.Guidence is order,I'm not sure where this leads or how I am thinking incorrectly.
I also have a bit of confusion surounding strictures: Why does a scalar defreference of an array force declarations to be made on the scalar and the array with the scalar name?Seems redundant,but strict seems important in the future of my studies.
Thanks

#! /usr/bin/perl use strict; use warnings; #a plethora of my's ...strict baffles me my @contents; my @aoa; my @ctags; my @ctagarray; my @aoac; my @headc; my @contentc; my @fontc; my @scalarclose; my $ctag; my $font; my $head; my $content; my $val; my $newlength; my $count; my $scalarclose; my $headc; my $fontc; my $contentc; my $i; #two arrays of arrays to populate @aoa=qw/header font content/ ; @aoac=qw/headerc fontc contentc/; # array of array values @contents=( ["html","head","body",], ["font","face","size","color"], ["h1","p","code"] ); #scalar ref to array for later population $scalarclose=\@aoac; #populate the aoa for (0...$#aoa){ $aoa[$_]=$contents[$_]; } #use contents of populated aoa foreach $val(@aoa){ # an incrementer hacked to use for populating # an aoa with modified values ++$i; $count=$i-1; #get values from original aoa and modifiy, #begin population of new aoa our $length=scalar @$val; for (0...$length-1){ $ctag="<\\$val->[$_]>"; push @ctags ,$ctag ; } $newlength=$length+1; @ctagarray=splice @ctags,0,$newlength; #this line is problematic @$scalarclose[$count]=map {$_}, @ctagarray; } #scalar refs to aoa $headc=$aoac[0]; $fontc=$aoac[1] ; $contentc=$aoac[2]; #print to see the populus >>broken<< print " $headc->[1]\n"; print " $fontc->[1]\n"; print " $contentc->[1]\n";

Replies are listed 'Best First'.
Re: Populating Arrays of Arrays
by Tanktalus (Canon) on Mar 03, 2005 at 19:11 UTC

    You have:

    #this line is problematic @$scalarclose[$count]=map {$_}, @ctagarray;
    I'm zeroing in on this. What you probably want is:
    @$scalarclose[$count]=[map {$_}, @ctagarray];
    An array can only hold a scalar, even if that scalar is actually a ref to something else. In this case, I've made the scalar into a ref to an anonymous array.

    Note that you have way too many declarations up front. Try moving the "my" closer to where each variable is first used. This is Perl, not Pascal. Thanks.

      Note that you have way too many declarations up front. Try moving the "my" closer to where each variable is first used. This is Perl, not Pascal. Thanks.

      Is that really a big deal? I declare the same way (although I will group declarations together).

        Is that really a big deal?

        It's indicative of a weak understanding of lexical scope. It's a symptom of a problem, not a problem in and of itself. Putting a huge block of my declarations at the top of the file is not a whole lot better than using package variables for everything. About the only benefit you get from strict is checking for typos.

        I prefer to scope variables as tightly as possible. That means, at the latest possible time and smallest possible block for the code to still work. Then, not only do I get protection against typos in variable names, I also get protection against inadvertant action-at-a-distance.

Re: Populating Arrays of Arrays
by davis (Vicar) on Mar 03, 2005 at 19:48 UTC
    Yikes. I don't intend to be rude at all, but your code is difficult to read and understand. I tried re-writing it, and I got this far:
    #!/usr/bin/perl use warnings; use strict; use diagnostics; use Data::Dumper; my @contents = ( [qw/html head body/], [qw/font face size color/], [qw/h1 p code/]); my @ctags; foreach my $row (@contents) { #$row will now be an array reference; #print Dumper $row; # if you want to see foreach my $value (@$row) { push @ctags, "<\\$value>"; } } print Dumper(\@ctags);

    To be honest, I'm not sure of your actual intentions in the scalarclose line, and the rest of the code features a lot of redundancy. What are your ultimate intentions? How close is this to doing what you want?

    Hint: Using Data::Dumper is a great way to see your variables' values.


    davis
    It wasn't easy to juggle a pregnant wife and a troubled child, but somehow I managed to fit in eight hours of TV a day.
      The object was to gain understanding of AOAs and strict. No long term plan for this particular piece of code. Thanks for taking the time to hack through my obtuse dialect.I'll pick up on your code and extract ideas for efficiency.
        Ah ok. Couldn't really see the eventual purpose :)
        General notes: declare "my" variables as late as possible: if you declare them inside a block (delineated delimited by braces), the variable won't be accessible (generally speaking) outside that block:
        my $foo; if($somevalue) { my $bar = "baz"; $foo = "monkey"; }

        In this piece of code, $bar is only accessible inside the if block. $bar, on the other hand, will disappear (or "go out of scope") as soon as the compiler reaches the closing "}".

        Declaring variables as late as possible is generally considered a Good Thing (this is probably an oversimplification, but it's a good start).

        I know I've said it already, but use Data::Dumper; to inspect variables.

        If you show what eventual output you want from this code, you'll probably get a response showing you one way of getting it.


        davis
        It wasn't easy to juggle a pregnant wife and a troubled child, but somehow I managed to fit in eight hours of TV a day.
Re: Populating Arrays of Arrays
by dmorelli (Scribe) on Mar 03, 2005 at 19:38 UTC
    #a plethora of my's ...strict baffles me

    You can group them together like this:

    #a plethora of my's ...no longer so baffling my (@contents, @aoa, @ctags, @ctagarray, @aoac, @headc, @contentc, @fo +ntc, @scalarclose); my ($ctag, $font, $head, $content, $val, $newlength, $count, $scalarcl +ose, $headc, $fontc, $contentc, $i);
Re: Populating Arrays of Arrays
by osunderdog (Deacon) on Mar 03, 2005 at 20:28 UTC

    First off, it is very good that you started with use strict! It'll definitely help you straighten these things out sooner than later.

    In answer to your question

    Why does a scalar defreference of an array force declarations to be made on the scalar and the array with the scalar name?
    Yes if you dereference an array and want to keep track of that reference, it'll have to be assigned into a scalar. However that scalar name doesn't have to correspond to the array name in any way.

    Perhaps a written description of what you're trying to accomplish would help us figure out how to extrapolate what you have into what you want.

    I can give you some ideas that may help... In my experience

    • seeing that many variable declarations is a flag that the code can be simplified.
    • Generally when I see looping structures like:

      for (0...$#aoa)

      or

      our $length=scalar @$val; for (0...$length-1)

      that it may be possible to loop over an array (ie for my $item (@aoa) rather than the indicies of that array.

    • You can populate a complex structure without having to assemble it as you are doing. For example where you are populating @aoa and then populating @contents and then looping through @aoa assigning elements to items out of @contents could be written:
      my @aoa = ('header',['html','head','body',], 'font',['font','face','size','color'], 'content',['h1','p','code'])

      But this makes me think that you really wanted a Hash of Arrays (HoA) rather than an Array of Arrays (AoA). Which would be:

      my %hoa = ('header',['html','head','body',], 'font',['font','face','size','color'], 'content',['h1','p','code'])

    There are other things...but that's all I've got time for for now...


    "Look, Shiny Things!" is not a better business strategy than compatibility and reuse.

Re: Populating Arrays of Arrays
by jdporter (Paladin) on Mar 03, 2005 at 22:27 UTC
    In addition to all the other fine advice given in this thread...
    #two arrays of arrays to populate @aoa=qw/header font content/ ; @aoac=qw/headerc fontc contentc/;

    Those are not arrays of arrays. They're simply arrays (that is, arrays of scalars).

    If you haven't done so lately, I highly recommend you read perlreftut, perllol, perldsc, and perlref (in that order).

Re: Populating Arrays of Arrays
by Roy Johnson (Monsignor) on Mar 03, 2005 at 22:07 UTC
    I have modified your code and added comments (with **) to let you know what's changed and what you might have misunderstood. Hope this helps.

    Caution: Contents may have been coded under pressure.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://436332]
Approved by Tanktalus
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (4)
As of 2024-04-23 15:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found