Почему shift считает, что получает параметр в скалярном контексте? - PullRequest
1 голос
/ 09 июня 2019

Я пытаюсь определить максимальное количество цифр любого числа в списке. Я обнаружил, что могу легко связывать функции Таким образом, следующий код работает должным образом:

use strict;
use diagnostics;

my @nums = qw/ 1 23 5432 45 /;
my @lengths = reverse sort map {1 + log($_)/log(10)} @nums;
my $max_length = shift @lengths;
printf "%d\n", $max_length;

Что дает ожидаемый результат 4.

Однако, когда я пытаюсь сделать сдвиг на той же строке, что и остальные операции со списком:

use strict;
use diagnostics;

my @nums = qw/ 1 23 5432 45 /;
my $max_length = shift reverse sort map {1 + log($_)/log(10)} @nums;
printf "%d\n", $max_length;

Я получаю ошибку

Experimental shift on scalar is now forbidden at - line 5, near "@nums;"

Почему shift считает, что ему передается параметр со скалярным контекстом, а наоборот и сортировке нет?

Спасибо

1 Ответ

4 голосов
/ 09 июня 2019

Обратите внимание, как документы для shift скажем

shift ARRAY
shift

Учитывая, что вы не передаете ему массив(переменная), но выражение оно сразу же отклоняет.

Позже у них есть комментарий (мой акцент)

Начиная с Perl 5.14, экспериментальная функция позволила shift принять выражение scalar .Этот эксперимент был признан неудачным и был удален с Perl 5.24.

Очевидно, что вы используете 5.24 или более новую версию.

Чтобы понять сообщение об ошибке, см. Документацию для более старой версии., вплоть до 5.22.4 , с

shift ARRAY
shift EXPR
shift

Обратите внимание, что * 1032 нет* там.Они продолжали объяснять, что означает этот EXPR

Начиная с Perl 5.14, shift может использовать скалярный EXPR, который должен содержать ссылку на необъявленный массив.Аргумент будет разыменован автоматически.Этот аспект shift считается очень экспериментальным.

Таким образом, более старая версия, увидев выражение, вычислила бы его в скалярном контексте и передала этот скаляр в shift.(Тогда он жаловался бы на то, что он не является ссылкой на массив.) Тем не менее упоминание " shift on scalar " должно быть информативным, но на данном этапе может быть просто запутанным.

Обратите внимание, что длину неотрицательного целого числа можно получить, взяв length этой строки

my @lengths = reverse sort map { length } @nums;

, что гораздо эффективнее, чем взятие логарифмов.

Кроме того, если вам действительно нужен только самый длинный

use List::Util qw(max);

my $max_length = max map { length } @nums;

, что в этом случае можно сделать еще более эффективно, например

my $max_length = length max @nums;
...