Pyritie Pyritie - 5 months ago 6
Perl Question

Perl line doesn't work when moved to separate function

I have an array that may or may not look like

[0, 1]
and I want to test for that.

This code (inside a method) works:

sub some_other_method {
my $self = shift;
...
if (scalar @myArray == 2 && @myArray[0] == 0 && @myArray[1] == 1) {
# this will successfully catch arrays that look like [0, 1]
}
}


If I move the contents of the
if
into a separate method and then call it, it doesn't work.

sub is_warning {
my $self = shift;
my @array = shift;
return scalar @array == 2 && @array[0] == 0 && @array[1] == 1;
}

...

sub some_other_method {
my $self = shift;
...
if ($self->is_warning(@myArray)) {
# this will not catch arrays that look like [0, 1]
}
}


If I add a
print @array;
to
is_warning
, it just prints a single number.

What am I doing wrong?

Answer

You've missed something crucial about perl - a subroutine in perl is only ever passed one single list of parameters in @_. So to pass an array, you either need to:

#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;

sub stuff {
   my ( $arg, @other_args ) = @_;
   print Dumper \@other_args;
   print "$_\n" for @other_args;
}


sub other {
   my ( $arg, $array_ref ) = @_;
   print Dumper $array_ref;
   print "$_\n" for @$array_ref;
}


my $param = "fish";
my @array = ( "wiggle", "wobble", "boo" );
stuff( $param, @array );
other( $param, \@array );

In the former - the sub is handed a list of values to do with what it will. In the latter, it's given two - $param and a reference to @array.

The reason you're only getting 1 in your case, is that shift is only pulling a single value off @_. So any extra arguments are getting left behind. You'll be able to see this with;

print Dumper \@_;