2013-09-26 7 views
4

Почему допустимо следующее:Почему между аргументами для сопоставления нет запятой?

my @ys = map { $_ * $_ } @xs; 

И следующие недопустимые?

my @ys = map { $_ * $_ }, @xs; 

ли map конструкция языка и на самом деле не функция, или существуют специальные правила для блоков?

+1

«Почему» в этих ситуациях «Потому что Ларри решил это сделать». :) –

ответ

3

map является список оператора и основная функция. Это простой синтаксис Perl, который не ожидает запятой после параметра блока для подпрограммы. Особенность map заключается в том, что она также может принимать форму map EXPR, LIST. Если бы это использовалось со стандартной подпрограммой, то EXPR было бы просто оценено и передано как первый параметр.

Параметры блока действительны для всех подпрограмм и могут использоваться, если вы применяете прототипы к определению подпрограммы. Например, вы могли бы определить mymap, что вел себя точно так же, написав

use strict; 
use warnings; 
use 5.010; 

sub mymap(&@) { 
    use Data::Dump; 
    my $sub = shift; 
    my @newlist; 
    push @newlist, $sub->($_) for @_; 
    @newlist; 
} 

say for mymap { $_ * $_ } 1, 2, 3; 

выход

1 
4 
9 

Но в целом вы должны избежать прототипов, если вы не знаете, точно что вы делаем. Как правило, лучший способ написать свой код.

8

Да, map - это языковая конструкция.

Как grep, it supports two different syntaxes:

map BLOCK LIST 
map EXPR, LIST 

BLOCK в вашем примере это просто простое выражение, так что эти два утверждения эквивалентны:

my @ys = map { $_ * $_ } @xs; 
my @ys = map $_ * $_, @xs; 
0

Это оператор, и каждый оператор определяет свой собственный синтаксис. Perl также предоставляет инструменты для подпрограмм.


Открытие линии perlfunc является:

Функции в этом разделе могут служить в качестве терминов в выражении. Они подразделяются на две основные категории: операторы списка и названные унарные операторы.

Так что пока map не является функцией в смысле C — они называются подпрограммами в Perl — это функция по определению Perl.

So map является оператором.Многие операторы имеют подпрограммы, которые отличаются от вызовов подпрограмм:

  • substr (должно следовать 1 до 4 разделенных запятыми выражений)
  • time (не может быть дан список аргументов)
  • map BLOCK LIST
  • print BLOCK LIST
  • delete HASH_ELEMENT
  • push ARRAY, LIST
  • lc (где предусмотрен вызывающий осциллографа $_)
  • EXPR + EXPR
  • т.д.

Подпрограммы могут совпадать или аппроксимируют синтаксис именованных операторов с использованием прототипов (например, sub mypush(\@@)) и Devel :: CallParser (например, loop).

Смежные вопросы