11

How exactly can I pass both scalar variables and array variables to a subroutine in Perl?

 my $currVal = 1;
 my $currValTwo = 1;
 my @currArray = ('one','two','three');
 my @currArrayTwo =('one','two','three');

 &mysub($currVal, $currValTwo,\@currArray, \@currArrayTwo);

 sub mysub() {

     # That doesn't work for the array as I only get the first element of the array
     my($inVal, $inValTwo, @inArray, @inArrayTwo) = @_;
 }
3
  • Which array, you are using two? Commented Jun 9, 2011 at 14:22
  • It happened with both but Blagovest answer fixed it! Commented Jun 9, 2011 at 14:47
  • I have been looking for this question all day. Thank you for asking this!!! Commented Mar 25, 2014 at 0:19

3 Answers 3

15

You need to fetch them as references because you've already passed them as references (by using the \ operator):

my($inVal, $inValTwo, $inArray, $inArrayTwo) = @_;

and then use the references as arrays:

@{$inArray}
Sign up to request clarification or add additional context in comments.

Comments

6

You pass the arguments as references, so you need to dereference them to use the values. Be careful about whether you want to change the original array or not.

sub mysub {
    my($inVal, $inValTwo, $inArray, $inArrayTwo) = @_;
    @{$inArrayTwo} = ('five','six','seven');
}

This will change the original @currArrayTwo, which might not be what you want.

sub mysub {
    my($inVal, $inValTwo, $inArray, $inArrayTwo) = @_;
    my @ATwo = @{$inArrayTwo};
    @ATwo = ('five','six','seven');
}

This will only copy the values and leave the original array intact.

Also, you do not need the ampersand in front of the sub name, from perldoc perlsub:

If a subroutine is called using the & form, the argument list is optional, and if omitted, no @_ array is set up for the subroutine: the @_ array at the time of the call is visible to subroutine instead. This is an efficiency mechanism that new users may wish to avoid.

You do not need empty parens after your sub declaration. Those are used to set up prototypes, which is something you do not need to do, unless you really want to.

2 Comments

Any idea how I can pass an XML::Writer by reference"? How would I dereference it in the subroutine?
I am not familiar with that module, but I would say any object gets passed with a scalar value.
0

So, for example: This is a using statement to search something in an array:

use List::Util qw(first);

This is the sub declaration:

sub GetIndex($$$);

This is the call to the sub (last parameter is: Default index value to give back if not found)

$searchedIndex = GetIndex(\@theArr, "valuesearched", 1);

This is the routine:

sub GetIndex($$$)
{
    my $inArray=shift;
    my @theArray= @{$inArray};
    my $searchedTag= shift;
    my $defaultVal= shift;

    my $retVal = first { $theArray[$_] eq $searchedTag} 0 .. $#theArray;
    if ((! defined $retVal)|| ($retVal<0)||($retVal>@theArray))
    {
        $retVal = $defaultVal;
    }
    return $retVal;
}

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.