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

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

So im a long time listener, first time caller....
now that the introductions are out of the way, im trying to work thru the ol' Perl 5 By Example, and im on the references chapter, getting a lil upset at the exercises..... my objective is to create multiple arrays, remove the first item from each array, and then display the number of characters removed.
im unable to even get my code to display the internal variable im dereferencing.
heres the code :
#!/usr/bin/perl poo ( (1..4), ("goo", "doo", "moo"), (6..9) ); sub poo { my($first, $second, $third) = @_; my @array = \@{$second}; print("@array"); }

its not quite being too friendly. would any of you kind monks be able to thrust me over to where the solution likes to hang out with all those unicorns and leprachauns... Thanks

Replies are listed 'Best First'.
Re: Dereferenced Arrays
by pmonk4ever (Friar) on Aug 19, 2009 at 00:01 UTC
    SirDonkey,

    Welcome to SoPW! As you may know, several of the Wiser Monks have gathered a massive amount of information in the Tutorials section of the Monastery.

    jdporter has an extremely interesting article entitled Arrays: A Tutorial/Reference and there is one about Multidem arrays by someone else in there. As well as articles by thezip, tye and others on many subjects.

    I've spent many an hour in the tomes there, the answer may not directly appear, but you might see something that may lead you to the answer.

    Try the Tutorials out, and maybe use the Super Search, there may be an answer behind that bush over there...

    Oh, yes, BTW, I didn't see "use warnings" & "use strict" in your code example, all seasoned Monks use these to help with debugging Perl scripts. "use diagnostics" may help in your array trials also!

    Good luck and welcome to Perl programming, where's there's always more than one way to do it!

    pmonk4ever

    "No trees were harmed in the creation of this node. However, a rather large number of electrons were somewhat inconvenienced."

Re: Dereferenced Arrays
by bobf (Monsignor) on Aug 19, 2009 at 00:24 UTC

    Welcome!

    I suspect that you are confusing arrays and lists. The distinction is a bit subtle (at first) but it is important. Instead of creating 3 arrays and calling poo with each set, you are actually creating one long list and calling the function once.

    Are you familiar with Data::Dumper (or any of its cousins)? It comes in very handy when trying to understand what is going on with data. Without changing how you call the function, add use Data::Dumper; to the top (right after  use strict; use warnings;) and try changing the sub to this:

    sub poo { print "in sub poo\n"; print Dumper( \@_ ); # rest of your code here }
    You will easily be able to determine what actually got passed to the sub.

    I need to emphasize use strict; again. If you had that in your code it would have given you a hint that something was amiss.

    Hopefully that will give you enough info to complete the exercise. Feel free to ask for further clarification if you can't get it to work.

      yeah i tend to use strict; when trying to debug... a lot of times it starts shreiking to high hell when i dont state the scope of the variables im using. so i normally throw it in there when im having trouble, but it didnt give me any errors. the only thing im having problems with at this point, is the fact that i cant print the contents of @array either by using it in quotes or not. still gives me

      ARRAY[ 0xmemaddy]
Re: Dereferenced Arrays
by jbt (Chaplain) on Aug 19, 2009 at 00:15 UTC
    You are getting unexpected results because the arguments are not array references and you are not dereferncing correctly.

    poo( [1..4], ["goo", "doo", "moo"], [6..9] ); sub poo { my($first, $second, $third) = @_; my @array = @$second; print("@array"); }
Re: Dereferenced Arrays
by SirDonkeyPunch (Novice) on Aug 19, 2009 at 00:34 UTC
    my bad, i figured it out, i had to assign
    my @array = @{$second};
    thanks for all the help. i havent been involved with a community thats so dedicated to what they enjoy.. this is great and i can gaurantee that after i RTFM, youll be hearing more from me, and i hope i can put what ive learn to work helping others here
      It's rather unusual (wasteful?) to copy the array. The following suffices:
      print("@$second");
        im learning so im just trying to get a grasp on all the functionality, not really trying to make utterly clean code, but moreso to understand the logic and flow of how i write programs and how i can manipulate data.
      i have successfully completed my goal of shifting out the first element in each array, gettin the length of the element, and eventually printing out the calculated amount of them all put together.

      this is by far the UGLIEST function i have seen. the flow control is wretched.... but its a beautiful fault in its own "crack in the liberty bell" sorta way

      poo ( [1..4], ["goo", "doo", "moo"], [6..9] ); sub poo { my($first, $second, $third) = @_; my @array = @{$second}; my $second = shift(@array); my $length = length($second); print("@array" , " $second", " $length\n"); @array = @{$first}; my $first = shift(@array); my $length1 = length($first); print("@array", " $first", " $length1\n"); @array = @{$third}; my $third = shift(@array); my $length2 = length($third); print("@array", " $third", " $length2\n"); my $result = $length + $length1 + $length2; print("$result\n"); }

      no indents..... no comments... completely unmaintainable... but complete. only thing i have to ask now, is what suggestion would someone make to incorporate a loop to go thru. would it call for @_ [ $index ] and then increasing it throughout the loop until it returns undef?


      thanks for all your guys' help, i really appreciate it.
        The first issue here is what is "poo". Let's assign "poo" to a variable before we try to call a sub named "poo_sub".
        #!/usr/bin/perl -w use strict; use Data::Dumper; my @poo = ( [1..4], ["goo", "doo", "moo"], [6..9] ); print Dumper (\@poo); #here the Dumper module is used (it is VERY handy) to #show the structure of @poo. __END__ $VAR1 = [ [ 1, 2, 3, 4 ], [ 'goo', 'doo', 'moo' ], [ 6, 7, 8, 9 ] ];
        The [....] are anonymous array references. A list is well, a list of things. In this case @poo is a list of anon ref's to other lists. There is some distinction between list and an array, but in general this is just Perl internals and for the purpose of understanding what a "@var" is, makes no difference.

        So let's call a subroutine with the list of 3 things in @poo:

        #!/usr/bin/perl -w use strict; use Data::Dumper; my @poo = ( [1..4], ["goo", "doo", "moo"], [6..9] ); #first we just have 3 things, just pass 'em! 3 things in the call! poo (@poo); sub poo { my ($lref1, $lref2, $lref3) = (my @lrefs) = @_; #yes can do this, here we don't need individual ref's #just shown to demo that you can do that... foreach (@lrefs) { dump_lref ($_); } } sub dump_lref { my $lref = shift; #same as $lref = @_; here print "@$lref\n"; } __END__ prints: 1 2 3 4 goo doo moo 6 7 8 9
        Now let's say that we don't want to pass the 3 things in the @poo list, we just want to pass a reference to the @poo list:
        #!/usr/bin/perl -w use strict; use Data::Dumper; my @poo = ( [1..4], ["goo", "doo", "moo"], [6..9] ); #now just pass a ref to the @poo list ..... poo (\@poo); sub poo { my $ref_of_ref_to_list = shift; foreach my $lref (@$ref_of_ref_to_list) #@does one level of de-ref { dump_lref($lref); } } sub dump_lref ###WHOA same sub we used before! { my $lref = shift; #same as $lref = @_; here print "@$lref\n"; } __END__ prints: 1 2 3 4 goo doo moo 6 7 8 9
        WHOA! same printout!

        I think that I should mention that unlike some other languages, @list, $list, %list, sub list{} are all different things.

        You might like PerlTidy. It doesn't do comments, but it does do a good job of normalizing your code layout. It has reasonable defaults which you can override if you prefer some other style. It formats your code as:

        poo( [ 1 .. 4 ], [ "goo", "doo", "moo" ], [ 6 .. 9 ] ); sub poo { my ( $first, $second, $third ) = @_; my @array = @{$second}; my $second = shift(@array); my $length = length($second); print( "@array", " $second", " $length\n" ); @array = @{$first}; my $first = shift(@array); my $length1 = length($first); print( "@array", " $first", " $length1\n" ); @array = @{$third}; my $third = shift(@array); my $length2 = length($third); print( "@array", " $third", " $length2\n" ); my $result = $length + $length1 + $length2; print("$result\n"); }

        Not much different, but very easy to do.

        I would use strict and warnings. If you did, you would see warnings like the following: