ProgrammingBackend Developer

What are the features of working with argument lists in Perl subroutines, and how to properly return values from a function?

Pass interviews with Hintsage AI assistant

Answer

In Perl, subroutines receive arguments through a special array variable @_, which automatically contains all the parameters passed. A peculiarity of Perl is that parameters are passed by reference, meaning that modifying elements inside the function changes their values outside.

To avoid unintended changes to the passed data, it is recommended to copy parameters into variables:

sub sum { my ($a, $b) = @_; return $a + $b; }

Perl functions always return a list of values, and the result of the function is the last computed list or an explicit return statement.

sub minmax { my ($x, $y) = @_; return ($x < $y ? $x : $y, $x > $y ? $x : $y); } my ($min, $max) = minmax(4, 7); # $min = 4; $max = 7

If a function is called in scalar context, it will return the count of returned elements, unless the result is enclosed in a scalar.


Trick Question

How to pass a large number of variables to a Perl function without accidentally changing the values of the original variables?

The unconscious response is: "You just need to copy the arguments into variables as usual!"

Correct answer:

Copying works only for scalars. If you are working with arrays or hashes, use references to manage data passing explicitly and avoid copying by reference:

sub modify { my ($arr_ref) = @_; push @$arr_ref, 'new'; # modifies the original array } my @data = (1, 2, 3); modify(\@data); # now @data = (1, 2, 3, 'new')

Story


Story 1

In a large report processing script, an internal function changed the values of elements in an array passed from the main program. As a result, the original data were corrupted after the function execution. The mistake was that the author of the function did not make copies of the input values, assuming that changes would be local, which is not true for @_ with arrays.


Story 2

When migrating scripts from Perl 4 (where variables were copied differently), the team faced a problem: passing nested hashes led to unexpected "leaks" of data between subroutine calls — modifying hash fields in one function affected other parts of the code. The reason was the reference to the hash in the @_ list.


Story 3

A developer implemented a function that returns an array of results, but in the calling place used scalar context: $count = func(@params);. It was expected that the variable would be assigned the value of the first returned element, but in reality, $count contained the number of elements in the list, leading to delays in calculations and confusion.