Perl: не может передать массив "на лету" подчиненному - PullRequest
5 голосов
/ 19 июля 2010

strftime (), согласно cpan.org:

print strftime($template, @lt);

Я просто не могу понять правильный рецепт Perl-кода для этого.Он продолжает сообщать об ошибке, когда я вызываю strftime ():

...
use Date::Format;
...
sub parse_date {
 if ($_[0]) {
  $_[0] =~ /(\d{4})/;
  my $y = $1;
  $_[0] =~ s/\d{4}//;
  $_[0] =~ /(\d\d)\D(\d\d)/;
  return [$2,$1,$y];
  }
 return [7,7,2010];
 }

foreach my $groupnode ($groupnodes->get_nodelist) {
    my $groupname = $xp->find('name/text()', $groupnode);
    my $entrynodes = $xp->find('entry', $groupnode);
    for my $entrynode ($entrynodes->get_nodelist) {
        ...
        my $date_added = parse_date($xp->find('date_added/text()', $entrynode));
        ...
        $groups{$groupname}{$entryname} = {...,'date_added'=>$date_added,...};
        ...
        }
    }
...

my $imday = $maxmonth <= 12 ? 0 : 1;
...

while (my ($groupname, $entries) = each %groups) {
    ...
    while (my ($entryname, $details) = each %$entries) {
        ...
        my $d = @{$details->{'date_added'}};
        $writer->dataElement("creation", strftime($date_template, (0,0,12,@$d[0^$imday],@$d[1^$imday]-1,@$d[2],0,0,0)));
        }
    ...
    }
...

Если я использую () для передачи необходимого массива с помощью strftime (), я получаю: Тип аргумента 2 в Date :: Format ::strftime должен быть массивом (не списком) в строке ./blah.pl 87, рядом с "))"

Если я использую [] для передачи требуемого массива, я получаю: Тип аргумента 2 в Date ::Format :: strftime должен быть массивом (не анонимным списком ([])) в строке ./blah.pl 87, рядом с "])"

Как я могу на лету передать массив в подпрограмму в Perl?Это легко сделать с помощью PHP, Python, JS и т. Д. Но я просто не могу понять это с помощью Perl.

РЕДАКТИРОВАТЬ: я сократил код до этих нескольких строк, и я все еще получилточно такая же проблема:

#!/usr/bin/perl

use warnings;
use strict;
use Date::Format;

my @d = [7,13,2010];
my $imday = 1;
print strftime( q"%Y-%m-%dT12:00:00", (0,0,12,$d[0^$imday],$d[1^$imday]-1,$d[2],0,0,0));

Ответы [ 4 ]

7 голосов
/ 19 июля 2010

Если требуется массив и у вас есть специальный список, вам нужно создать массив.Это не должна быть отдельная переменная, вы можете просто сделать:

strftime(
    $date_template,
    @{ [0,0,12,$d[0^$imday],$d[1^$imday],$d[2],0,0,0] }
);

Я понятия не имею, почему Date :: Format подвергнет вас этой отвратительности, а не просто ожидает нескольких скалярных параметров;кажется бессмысленным (и вопреки тому, как другие модули реализуют strftime).Грэм Барр обычно проектирует лучшие интерфейсы, чем этот.Возможно, это произошло в то время, когда прототипы все еще казались отличной идеей для общих целей.

3 голосов
/ 19 июля 2010

Чтобы использовать список в качестве анонимного массива для, скажем, интерполяции строк, вы можете написать

print "@{[1, 2, 3]}\n";

, чтобы получить

1 2 3

Тот же метод предоставляет обходной путь для Date::Format::strftime Прикольный прототип:

print strftime(q"%Y-%m-%dT12:00:00",
               @{[0,0,12,$d[0^$imday],$d[1^$imday]-1,$d[2],0,0,0]});

Выход:

1900-24709920-00T12:00:00
2 голосов
/ 19 июля 2010

Обычно легко передавать массивы "на лету" в подпрограммы Perl.Но Date::Format::strftime - это особый случай со специальным прототипом ($\@;$), который не допускает аргументов «списка» или «назначения списка»:

strftime($format, (0,0,12,13,7-1,2010-1900));      # not ok
strftime($format, @a=(0,0,12,13,7-1,2010-1900));   # not ok

Обходной путь - вы должны вызвать strftimeс переменной массива.

my @time = (0,0,12,13,7-1,2010-1900);   # note: @array = ( ... ), not [ ... ]
strftime($format, @time);
0 голосов
/ 19 июля 2010

Я снова посмотрел и вижу реальную проблему в этом коде:

my $d = @{$details->{'date_added'}};
    $writer->dataElement("creation", strftime($date_template, (0,0,12,@$d[0^$imday],@$d[1^$imday]-1,@$d[2],0,0,0)));

В частности @{$details->{'date_added'}} - это разыменование.Но вы присваиваете его скалярной переменной, и вам не нужно разыменовываться в строке под ней:

my @d = @{$details->{'date_added'}};
    $writer->dataElement("creation", strftime($date_template, (0,0,12,$d[0^$imday],$d[1^$imday]-1,$d[2],0,0,0)));

Я создал регулярный массив для вашей ссылки @d и только что получил к нему доступкак обычный массив ($d[ ... ] вместо @$d[ ... ])

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...