6

I want to call a subroutine by passing around 4 arrays to it and then get the first value of each array and then create a new array(array of first elements of arrays that are passed) in the subroutine and then return back that array. Here is the code I tried with

my @a = (97,34,6,7);
my @b = ("A", "B", "F", "D");
my @c = (5..15);
my @d = (1..10);
my @tailings = popmany ( \@a, \@b, \@c, \@d );

print @tailings;

sub popmany {
    my @retlist = ();
    for my $aref (@_) {            #1
        my $arrele = @$aref;       #2
        push @retlist , $arrele    #3
    }
    return @retlist;
}

Here in #1 I use a loop and get the first array , then in line 2 I assign the whole array to a variable, thinking that by default the perl will only store the first variable of array into @arrele. the I push the $arrele to a new array @retlist , Sorry I dint refer any notes, so my procedure might be wrong. But this is throwing me a output like 441110

which has no sense.

Please explain me the code how can I do that.

1
  • popmany as a name is doubly misleading. pop removes the last element of an array and returns it. This returns the first value without altering the arrays. Commented Nov 11, 2011 at 11:57

4 Answers 4

16

It's here:

my $arrele = @$aref;

where you're asking perl to put @{$aref} into scalar context, which returns the length (number of elements in) the array pointed at by $aref.

Instead try:

my $arrele = $aref->[0];

which will access the first element of the array instead.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks ... Can you tell me why my $arrele = $aref[0]; doesn't work ?
Because $aref is an array ref and you're trying to access it as an array. Try @$aref[0] instead if you desperately want to avoid $aref->[0] which is a lot clearer.
$aref[0] means "first element of array @aref" but $aref is a scalar containing a reference to some other array, so you need to use -> to dereference it first.
$$aref[0] is also a viable option.
I thought I wrote that in the comment above, but looking at it again, I see that I've accidentally used a one element array slice. :$
6

The line

my $arrele = @$aref;  

assigns the length of the @$aref array to $arrele. To get the first element of the array you could use any of:

my $arrele = $$aref[0];
my $arrele = $aref->[0];    
my ($arrele) = @$aref;  # note the parenthesis which create list context

Also, since you generate a list based on another list, you could use map:

sub popmany {
    return map $_->[0], @_;
}

Comments

1

Far more simply written as

  sub popmany 
  {
    map $_->[0], @_;
  }

1 Comment

Please leave simple code to codegolf questions. Easy code is the way to go, and this is not the easy way.
1
sub popmany { 
    my @retlist = (); 
    for my $aref (@_) { #1 
        my $arrele = @$aref[0]; #2 
        push @retlist , $arrele#3 
    } 
    return @retlist; 
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.