0

Im passing array by reference to a subroutine:

my @template_ops;
handle_templates_with_post_mod(\@template_ops);

sub handle_templates_with_post_mod
{
    my @my_template_ops    = @{$_[0]};
    unshift (@my_template_ops), 'O';
}

but after calling the subroutine the array still empty, I have tried:

sub handle_templates_with_post_mod
{
    my $my_template_ops    = shift;
    unshift (@$my_template_ops), 'O';
}

but I get this error: Can't use string ("...") as an ARRAY ref while "strict refs"

2 Answers 2

4

Four issues:

  1. ALWAYS turn on use strict; use warnings;

  2. Then unshift (@$my_template_ops), 'O'; would have produced Useless use of unshift with no values at ./t.pl line 17.. You have set the parens () wrong. Either write unshift (@$my_template_ops, 'O'); or just leave them off completely: unshift @$my_template_ops, 'O';

  3. The code my @my_template_ops = @{$_[0]}; generates a copy of the supplied array reference and you are manipulating the copy. Thus you don't see the effect at top level.

  4. The 2nd version of your function works because you operate on the supplied array ref and just dereference it for the unshift call.

Working version:

use strict;
use warnings;
use Data::Dumper;

my @template_ops;
handle_templates_with_post_mod(\@template_ops);

print Data::Dumper::Dumper( \@template_ops );

sub handle_templates_with_post_mod
{
    my $my_template_ops    = shift;
    unshift @$my_template_ops, 'O';
}

Output:

$VAR1 = [
          'O'
        ];
Sign up to request clarification or add additional context in comments.

Comments

2

When you give the dereferenced array a name, it becomes a copy. To operate on an array ref and affect the original array, you either need to use it as a ref, or dereference it without giving it a new name (using the @ operator to dereference).

my $arrayRef = ...;
push @{$arrayRef}, 42;
my $hashRef = ...;
delete $hashRef->{key};

1 Comment

@PerlDuck Thanks. I changed it to a hash ref, since deleting hash elements is safe and still illustrates the syntax.

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.