2013-04-18 2 views
1

В добавлении метода to_json (для преобразования благословенных ссылок через JSON.pm) в CGI :: Cookie, если я делаю это: ошибкуДействительно странно Perl ошибка синтаксиса, добавив метод to_json к пакету

package CGI::Cookie; 
sub TO_JSON { 
    return { 
     map { name => $_->name, 
       value => $_->value, 
       domain => $_->domain, 
       path => $_->path, 
       expires => $_->expires } 
      shift 
    } 
} 

синтаксиса на XXX.pm линии 76, возле "сдвига" ошибка синтаксиса в XXX.pm линии 77, возле "}" Компиляция не удалось в требуют в (Eval 50) линии 3.

Но если я это сделать:

package CGI::Cookie; 
sub TO_JSON { 
    return { 
     map { ''.'name' => $_->name, 
       value => $_->value, 
       domain => $_->domain, 
       path => $_->path, 
       expires => $_->expires } 
      shift 
    } 
} 

не работает

Не может для меня жизнь выяснить почему. Также просто не цитирует «имя». I должны конкатенировать пустую строку, чтобы она работала.

Я озадачен.

ответ

2

Perl-грамматика немного неоднозначна, когда дело доходит до блоков и анонимных hashrefs. Когда Perl не может угадать, вы можете заставить правильную интерпретацию:

  • Hashref по +{ ... }
  • кодоблок по {; ... }

Принуждение блок после map быть кодоблок решает проблему , Раньше считалось, что этот блок был анонимным хешем, и пропустил запятую перед shift: map может иметь форму map EXPR, LIST, а hashref является допустимым выражением.


Суб использует злоупотребляет map, чтобы назначить один элемент $_. Было бы лучше быть написано:

sub TO_JSON { 
    my $o = shift; # my $_ should work as well, but that is beside the point 
    return +{ 
     name => $o->name, 
     value => $o->value, 
     domain => $o->domain, 
     path => $o->path, 
     expires => $o->expires, 
    }; 
} 

Но это может быть сокращено до

sub TO_JSON { 
    my $o = shift; 
    return +{ 
     map { $_ => $o->$_() } qw/name value domain path expires/ 
    }; 
} 
+0

Спасибо. Очень странно, хотя, поскольку предполагается, что кодовым блоком является предпочтительным первым аргументом для map(), я бы подумал, что это будет первое, что предположил бы Perl. Это произведение также хорошо: package CGI :: Cookie; югу to_json { возвращения { отображения {; имя => $ _-> имя, значение значения => $ _-> домен => $ _-> домен, путь => $ _-> путь, expires => $ _-> expires} shift } } –

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