What does @_ -1 mean in Perl?
I'm trying to translate a Perl script to PHP and I'm having trouble with some Perl things. For instance, what does @_ -1
mean? And how do I write it in PHP?
The whole function is as follows:
sub variance {
my $sum = sum_squares (@_);
my $deg = @_ - 1;
return $sum/$deg;
}
Ok, all the subroutines are as follows:
sub mean { # mean of values in an array
my $sum = 0 ;
foreach my $x (@_) {
$sum += $x ;
}
return $sum/@_ ;
}
sub sum_squares { # sum of square differences from the mean
my $mean = mean (@_) ;
my $sum_squares = 0 ;
foreach my $x (@_) {
$sum_squares += ($x - $mean) ** 2 ;
}
return $sum_squares ;
}
sub variance { # variance of values in an array
my $sum_squares = sum_squares (@_) ;
my $deg_freedom = @_ - 1 ;
return $sum_squares/$deg_freedom ;
}
sub median { # median of values in an array
my @sorted = sort {$a <=> $b} (@_) ;
if (1 == @sorted % 2) # Odd number of elements
{return $sorted[($#sorted)/2]}
else # Even number of elements
{return ($sorted[($#sorted-1)/2]+$sorted[($#sorted+1)/2]) / 2}
}
sub histogram { # Counts of elements in an array
my %histogram = () ;
foreach my $value (@_) {$histogram{$value}++}
return (%histogram) ;
}
Please bear with me because its my first time with Perl. From what I've seen (tested), the right answer in this case is the one of David Dorward. I 开发者_如何学Pythondo have another question regarding this set of subroutines that is here.
In this case,@_
is the arguments passed to the subroutine, as a list.
Taken in scalar context, it is the number of elements in that list.
So if you call: variance('a', 'b', 'c', 'd');
, $deg
will be 3.
Like already said, it is the array of arguments passed to the function. It's equivalent in PHP would be
func_get_args()
— Returns an array comprising a function's argument listfunc_num_args()
— Returns the number of arguments passed to the function
The entire function would be
function variance() {
$sum = sum_squares(func_get_args());
$deg = func_num_args() - 1;
return $sum/$deg;
}
// echo variance(1,2,3,4,5); // 13.75 (55/4)
For sum_squares
, there is no native function in PHP. Assuming it does what the name implies, e.g. raising each argument to the power of 2 and then summing the result, you could implement it as
function sum_squares(array $args) {
return array_reduce(
$args, create_function('$x, $y', 'return $x+$y*$y;'), 0
);
}
// echo sum_squares( array(1,2,3,4,5) ); // 55
Replace create_function
with a proper lambda if you are on PHP5.3
It's the number of arguments, passed to the variance
subroutine minus one (or index of the last element in the @_
array). @_
is used in scalar context here.
@_ is the incoming parameter to the sub, but referred in scalar context is the number of parameters.
In php will be something like:
function variance() {
$arguments = func_get_args();
$sum = sum_squares($arguments);
$deg = sizeof($arguments);
return $sum/$deg;
}
@_
is the list of parameters being paassed into the subroutine. When you use it in a non-scalar context such as:
sum_squares (@_)
you get the list, so presumably that would return the sum of the squares of all the numbers in that list (see comment below however).
When used in a scalar context, you get the length so in your case it would be the number of items in the $@
function list.
So your variance function is probably (I say probably since I don't have access to the sum_squares
source code) calculating:
variance = arr[0]^2 + arr[1]^2 + ... + arr[N-1]^2
--------------------------------------
N - 1
on the array of values being passed into your function.
I have to say that my understanding of variance is at odds with that (thouugh it's been a while since I did any stats). I'm pretty certain it's supposed to involve the sum of the squares of the differences between the values and the mean, not the values themselves. I suspect there's more happening inside sum_squares
than its simple name implies.
To supplement the other answers, the @_
Special Variable is described in the free official Perl online documentation (along with other variables):
Within a subroutine the array @_ contains the parameters passed to that subroutine. See perlsub.
In function @_ will have list of function argument which is passed to the function . Actually when we are trying to assign the list value to the scalar , it will assign the length of the array. And Here -1 is for accessing the last element of the @_ array
sub test { my $count = @_ ; # Now it will assign the number of function arguments # Because we are trying to assign as a scalar. >print "Output:$count\n" ; # Output : 4 ($count ) = @_ # Now it will assign the first element of the functions print "Output:$count\n" ; # OUtput: 10 # Because we are trying to assign as list values , So ,list as only one variable . # So , first element gets assigned. } &test ( 10,20,30,40 ) ;
精彩评论