Я не могу сказать, почему Ларри не заставил map
, grep
, а другие функции списка работают на @_
, как pop
и shift
, но я могу сказать вам, почему я не смог быт.Раньше переменные по умолчанию были в моде, но программисты Perl обнаружили, что большинство поведений «по умолчанию» вызывают больше проблем, чем решают.Я сомневаюсь, что они сделали бы это сегодня языком.
Первая проблема - запоминание того, что делает функция, когда не передано аргументов.Это действует на скрытую переменную?Который из?Вы просто должны знать наизусть, и это делает намного больше работы по изучению, чтению и написанию языка.Вы, вероятно, поймете это неправильно, а это означает ошибки.Этого можно избежать, если Perl будет последовательным (т. Е. ВСЕ функции, которые принимают списки, работают с @_, а ВСЕ функции, которые принимают скаляры, работают с $ _), но есть и другие проблемы.
Вторая проблема - это поведениеизменения в зависимости от контекста.Возьмите какой-нибудь код вне подпрограммы или поместите его в подпрограмму, и вдруг он работает по-другому.Это делает рефакторинг сложнее.Если вы заставили его работать на просто @_
или просто @ARGV
, то эта проблема исчезнет.
В-третьих, переменные по умолчанию имеют тенденцию к тихому изменениюа также читать.$_
опасен по этой причине, вы никогда не знаете, когда что-то заменит это.Если бы было принято @_
в качестве переменной списка по умолчанию, это поведение, вероятно, утекло бы.
В-четвертых, это, вероятно, привело бы к сложным синтаксическим проблемам.Я полагаю, что это было одной из первоначальных причин, препятствующих его добавлению в язык, когда в моде было $_
.
Пятый, @ARGV
по умолчанию имеет некоторый смысл, когда вынаписание сценариев, которые в основном работают с @ARGV
... но это не имеет никакого смысла при работе с библиотекой.Программисты Perl перешли от написания быстрых сценариев к написанию библиотек.
В-шестых, использование $_
по умолчанию является способом объединения скалярных операций без необходимости перезаписи переменной снова и снова.Это могло бы быть смягчено, если бы Perl был более последовательным в своих возвращаемых значениях, и если регулярные выражения не имели специального синтаксиса, но у вас он есть.Списки уже могут быть объединены в цепочку, map { ... } sort { ... } grep /.../, @foo
, так что сценарий использования обрабатывается более эффективным механизмом.
Наконец, он имеет очень ограниченное использование.Очень редко вы хотите передать @_
в map
и grep
.Проблемы со скрытыми значениями по умолчанию намного больше, чем избегание ввода двух символов.Эта экономия места может иметь немного больше смысла, когда Perl в основном предназначен для быстрой и грязной работы, но не имеет смысла при написании чего-либо, кроме нескольких страниц кода.
PS shift
по умолчанию@_
нашел нишу в my $self = shift
, но я нахожу, что это светит только потому, что обработка аргументов в Perl очень плохая.