Perl variable definition

So I have nearly no experience with Perl and for work I have to analyze some messy Perl code and find a mistake. I am having serious trouble understanding the code because of the massive usage of $_ which is so confusing. So if you have any advice how to get into Perl quickly please tell me. However that is not my main question.

I've just bumped into a line of code that I dont understand. It is inside of a Perl Module right after the listing of all the librarys. So here is the line:

my (@array1,@array2) = ()

Later then one of the arrays is used in the following case inside of the constructor that is called with a hash as argument:

my ($object,$anyHashReference) = @_;
@array2 = someValue;
foreach (keys %{$anyHashReference})
{
    push(@array1,$_);
    push(@array1,$anyHashReference->{$_});
}
return bless {}, $object;

So what I don't understand is what exactly is archieved with the variable declaration for multiple variables and what does the push function do in this case.

Thanks in advance!

Upvotes: 0

Views: 70

Answers (2)

ikegami
ikegami

Reputation: 386331

The following three snippets are equivalent:

my $x;
my $y;
($x, $y) = foo();

(my $x, my $y) = foo();

my ($x, $y) = foo();

In every case, the first scalar returned by expression on the right-hand of the assignment is assigned to $x, and the second to $y. (Any extras are ignored.)


There's a catch when one of the variables to which values are being assigned is an array (or hash).

my (@a, ...) = foo();

Perl doesn't know how many of the scalars returned by the RHS should be assigned to the array, and how many of the scalars should be assigned to the subsequent variables, so it assigns them all to the array.

This means the following are equivalent:

my @a;
my @b;
@a = foo();

(my @a, my @b) = foo();

my (@a, @b) = foo();

my @a = foo();
my @b;

Obviously, the last one is clearest.


Finally, let's look at your specific case. You have

my (@array1, @array2) = ();

As mentioned above, this is equivalent to

my @array1 = ();
my @array2;

Since Perl creates arrays empty[1], we could simply write

my @array1;
my @array2;

By combining these, we can make the code more compact.

my (@array1, @array2);

Both of these final options are fine, but I think the one used by the author your code is pretty horrible. It's misleading and unncessarily noisy.


  1. Hashes are also created empty, and scalars are created undefined.

Upvotes: 1

Grinnz
Grinnz

Reputation: 9231

The variable definition with my declares those variables for the current lexical scope, whereas doing that in a smaller scope, such as within the foreach loop or subroutine, would mean they aren't available outside it, and each iteration would get a new instance of that variable. (A lexical scope is defined what you visibly see in the source code, it's either bounded by a block {} or the file itself.) The = () here actually does nothing, since arrays start out empty already.

The foreach loop aliases each element of the list to $_ since no variable was provided to it. It could also be written foreach my $key (keys %{$anyHashReference}) and then you would use $key instead of $_, and this is in fact much safer because it does not rely on a global variable. The documentation for $_ lists all of the core functionality that could end up using it.

In either case, these push statements are adding the current item to @array1, and then the value from the hash reference at that key.

Upvotes: 2

Related Questions