Что означает @_ -1 в Perl? - PullRequest
       9

Что означает @_ -1 в Perl?

5 голосов
/ 01 марта 2010

Я пытаюсь перевести скрипт Perl на PHP, и у меня возникают проблемы с некоторыми вещами на Perl. Например, что означает @_ -1? И как мне написать это на PHP?

Вся функция выглядит следующим образом:

sub variance {
    my $sum = sum_squares (@_);
    my $deg = @_ - 1;
    return $sum/$deg;
}

Хорошо, все подпрограммы выглядят следующим образом:

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) ;
}

Пожалуйста, потерпите меня, потому что это мой первый раз с Perl. Из того, что я видел (проверял), правильный ответ в этом случае - это ответ Дэвида Дорварда. У меня есть еще один вопрос относительно этого набора подпрограмм, который здесь .

Ответы [ 7 ]

9 голосов
/ 01 марта 2010

В этом случае @_ - это аргументы, передаваемые подпрограмме в виде списка.

В скалярном контексте это число элементов в этом списке.

Так что если вы позвоните: variance('a', 'b', 'c', 'd');, $deg будет 3.

7 голосов
/ 01 марта 2010

Как уже говорилось, это массив аргументов, передаваемых функции. Это эквивалентно в PHP будет

  • func_get_args() - Возвращает массив, содержащий список аргументов функции
  • func_num_args() - Возвращает количество аргументов, переданных функции

Вся функция будет

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)

Для sum_squares в PHP нет встроенной функции. Предполагая, что он делает то, что подразумевает название, например возводя каждый аргумент в степень 2 и затем суммируя результат, вы можете реализовать его как

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

Замените create_function на правильную лямбду , если вы используете PHP5.3

2 голосов
/ 01 марта 2010

@ _ является входящим параметром для подпрограммы, но в скалярном контексте указано количество параметров.

В php будет что-то вроде:

function variance() {
    $arguments = func_get_args();
    $sum = sum_squares($arguments);
    $deg = sizeof($arguments);
    return $sum/$deg;
}
2 голосов
/ 01 марта 2010

Это число аргументов, переданных подпрограмме variance минус один (или индекс последнего элемента в массиве @_). @_ используется здесь в скалярном контексте.

1 голос
/ 01 марта 2010

В дополнение к другим ответам специальная переменная @_ описана в бесплатной официальной онлайн-документации по Perl (вместе с другими переменными):

Внутри подпрограммы массив @_ содержит параметры, переданные этому подпрограмма. Смотрите perlsub.

1 голос
/ 01 марта 2010

@_ - список параметров, передаваемых в подпрограмму. Когда вы используете его в нескалярном контексте, например:

sum_squares (@_)

вы получите список, так что, предположительно, он вернет сумму квадратов всех чисел в этом списке (однако см. Комментарий ниже).

При использовании в скалярном контексте вы получаете длину, поэтому в вашем случае это будет количество элементов в списке функций $@.

Итак, ваша дисперсионная функция, вероятно (я говорю, вероятно, так как у меня нет доступа к исходному коду sum_squares), вычисляет:

variance = arr[0]^2 + arr[1]^2 + ... + arr[N-1]^2
           --------------------------------------
                            N - 1

в массиве значений, передаваемых в вашу функцию.

Я должен сказать, что мое понимание дисперсии расходится с этим (хотя я давно уже делал какие-либо статистические данные). Я почти уверен, что он должен включать сумму квадратов разностей между значениями и средним значением, не самих значений. Я подозреваю, что внутри sum_squares происходит больше, чем предполагает его простое имя.

0 голосов
/ 01 марта 2010

В функции @_ будет список аргументов функции, которые передаются в функцию. На самом деле, когда мы пытаемся присвоить значение списка скаляру, он назначит длину массива. А вот -1 для доступа к последнему элементу массива @_

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 ) ; 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...