Programming:Perl:Unary vs List vs Array

From Knowledge base
Revision as of 19:55, 1 April 2018 by Celogeek (talk | contribs) (Created page with "Category:ProgrammingCategory:Perl <seo title="Perl Unary vs List vs Array" metakeywords="programming,perl,unary,list,array" /> The common misunderstanding in Perl is...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

The common misunderstanding in Perl is the difference between a list, an array, and the unary operation coma:

  • a list : (1, 2, 3)
  • an array: @my_array containing (1, 2, 3)
  • the unary operation coma: $operation1, $operation2, $operation3

Perl uses the context to act practically over logically. That lead to unexpected behavior if you mislead each of this concept.

The 3 contexts are void context, list context, scalar context. We focus on the scalar context here.

List versus Array

When you declare an array :

my @my_array;

And use functions like push or scalar:

push @my_array, 1;
my $total_elements = scalar @my_array;

A list is immutable. It is impossible to apply a change to it:

push (1,2,3), 4

It is equivalent to try to push 2, 3, 4 into the constant 1. That does not work.

Unary operator

my $x = 4, 5, 6;

It is equivalent to:

my $x = 4 and 5 and 6;

So $x = 4 in that case.

Scalar context

List

my $x = (4, 5, 6);

We use a list in a scalar context. In that case, the list will return the last element.

So $x = 6.

Array

my $x = @{[4, 5, 6]};
# short for :
my @y = (4, 5, 6);
my $x = @y;

We use an array in a scalar context. In that case, the array returns the size of the array.

So $x = 3.

Mix it

my $x = @{[4, 5, 6]}, 7;

The operation assign the array to $x, in that case that mean the size of the array, then execute the constant 7.

So $x = 3.

my $x = (@{[4, 5, 6]}, 7);

The array in a list context expands into a list with '4, 5, 6', and then we add 7. It creates a list with 4, 5, 6, 7. A list returns the last element in a scalar context.

So $x = 7.

Unary operator

And take care of the unary operator against the list :

my @x = 4, 5, 6;

Here we don't have a list assign to an array, but the unary operator.

So @x = (4).

If you use a list:

my @x = (4, 5, 6);

Each element of the list is added to the array.

So @x = (4, 5, 6).

If we are in a function, the behavior is different, because of the practical other logical.

sub t_unary {
 return 4, 5, 6;
}
$x = t_unary();
# $x = 6
sub t_list {
 return (4, 5, 6);
}
$x = t_list();
# $x = 6
sub t_array {
 return @{[4, 5, 6]};
}
$x = t_array();
# $x = 3
sub t_mix_unary_array {
 return @{[4, 5, 6]}, 7;
}
$x = t_mix_unary_array();
# $x = 7
sub t_mix_list_and_array {
 return (@{[4, 5, 6]}, 7);
}
$x = t_mix_unary_array();
# $x = 7

The unary operation is transformed into a list before the function returns his result. When we mix an array and a list, it results in a list; then the latest result is returned in scalar context. When we return an array in a scalar context, the result is the size of the array.

We can replace the array return by:

sub t_array {
 return wantarray ? 3 : (4, 5, 6);
}

The context can be used to return the most practical result.

An example with the "sort_in_place" function :

sub sort_in_place{
   my ($t) = @_;
   if (wantarray()) {
       # list context
       return sort @$t 
    } elsif (defined wantarray()) {
       # in scalar context
       return scalar(@$t);
    } else { 
       # in void context
       @$t = sort @$t;
       return
    }
  }
}

This method checks the context. The "wantarray" (poorly named), can be used to get the context.

"wantarray" has differents value in the context:

  • value "1" in a list context
  • value "" (empty string) in a scalar context
  • value undef in a void context

In a list context:

my @x = (5,4,3);
my @y = sort_in_place(\@x);

# @x = 5, 4, 3
# @y = 3, 4, 5

In scalar context :

my @x = (5,4,3);
my $y = sort_in_place(\@x);

# @x = 5, 4, 3
# $y = 3

In void context :

my @x = (5,4,3);
sort_in_place(\@x);

# @x = 3, 4, 5

Conclusion

Never, ever guest the behavior of a function based on what you think it should behave. Read the documentation or look at the code.

Source: LinkedIn: finding the index of an element in an array



Share your opinion