Where does a Perl function get values that are not in real parameters?
I came across the following Perl routine get_billable_pages
while chasing a bug. It takes 12 arguments.
sub get_billable_pages {
my ($dbc,
$bill_pages, $page_count, $cover_page_count,
$domain_det_page, $bill_cover_page, $virtual_page_billing,
$job, $bsj, $xqn,
$direction, $attempt,
) = @_;
my $billable_pages = 0;
if ($virtual_page_billing) {
my @row;
### Below is testing on the existence of the 11th and 12th parameters ###
if ( length($direction) && length($attempt) ) {
$dbc->xdb_execute("
SELECT convert(int, value)
FROM job_attribute_detail_atmp_tbl
WHERE job = $job
AND billing_sub_job = $bsj
AND xqn = $xqn
AND direction = '$direction'
AND attempt = $attempt
AND attribute = 1
");
}
else {
$dbc->xdb_execute("
SELECT convert(int, value)
FROM job_attribute_detail_tbl
WHERE job = $job
AND billing_sub_job = $bsj
AND xqn = $xqn
AND attribute = 1
");
}
$cnt = 0;
...;
But sometimes it is called with only 10 arguments
$tmp_det = get_billable_pages(
$dbc2,
$row[6], $row[8], $row[7],
$domain_det_page, $bill_cover_page, $virtual_page_billing,
$job1, $bsj1, $row[3],
);
The function checks the 11th and 12th arguments.
-
What are the 11th and 12th arguments when only 10 arguments are passed to the function?
-
Is it a mistake to call a function with only 10 arguments, because the 11th and 12th arguments become random values?
-
I think this might be the source of the error, because the 12th argument had a funky meaning when the program failed.
-
I have not seen any other function definition that only takes 10 arguments.
source to share
The values are copied from the parameter array @_
to the scalar variable list.
If the array is smaller than the list, then the redundant variables are set to undef
. If the array is longer than the list, then the extra array elements are ignored.
Note that the original array has @_
not been changed by the assignment. No values are created or lost, so it remains the final source of the actual parameters passed when the subroutine is called.
ikegami suggested that I provide some Perl code to demonstrate assigning arrays to lists of scalars. Here is this Perl code based mainly on editing it
use strict;
use warnings;
use Data::Dumper;
my $x = 44; # Make sure that we
my $y = 55; # know if they change
my @params = (8); # Make a dummy parameter array with only one value
($x, $y) = @params; # Copy as if this is were a subroutine
print Dumper $x, $y; # Let see our parameters
print Dumper \@params; # And how the parameter array looks
Output
$VAR1 = 8;
$VAR2 = undef;
$VAR1 = [ 8 ];
Thus, both parameters $x
and $y
change, but if there are not enough values in the array, it is used instead undef
. It is as if the original array was expanded with elements indefinitely undef
.
Now let's look at the logic of the Perl code. undef
evaluates to false for the purpose of conditional tests, but you are applying a statement length
like this
if ( length($direction) && length($attempt) ) { ... }
If you have use warnings
, as usual, Perl usually generates a warning Use of uninitialized value
. However, it length
is unusual in this case that if you are asking for the length of a value undef
(and you are using version 12 or later of Perl 5), it will simply return undef
rather than warn you.
As for "I have not seen any other function definition that only takes 10 arguments", Perl does not have function templates like C ++ and Java, then for the code it was accepted it depends on the code in the subroutine and behaves accordingly.
source to share