perl6 метод класса действий Grammar кажется не унаследованным, именованный захват кажется не сделанным

Я пытаюсь разобрать CSV-файл, чтобы делать простые вещи: извлечь фамилию, идентификатор и день рождения и изменить формат дня рождения с m/d/yyyy на yyyymmdd.

(1) Я использовал именованный захват для дней рождения, но кажется, что метод именованного захвата не вызывается, чтобы сделать то, что я хочу.

(2) Наследование методов действия грамматики не работает для именованных захватов.

Что я сделал не так?

my $x = "1,,100,S113*L0,35439*01,John,JOE,,,03-10-1984,47 ELL ST #6,SAN FRANCISCO,CA,94112,415-000-0000,,5720,Foo Bar,06-01-2016,06-01-2016,Blue Cross,L,0,0";

# comma separated lines
grammar insurCommon {
    regex aField  { <-[,]>*? }
    regex theRest { .* }
}    

grammar insurFile is insurCommon {
    regex TOP { <aField> \,\,  # item number
        <aField> \,            # line of business
        <aField> \,            # group number
        <ptID=aField> \,       # insurance ID, 
        <ptLastName=aField> \, # last name, 
        <aField> \,\,\,        # first name
        <ptDOB=aField> \,      # birthday
        <theRest> }
}

# change birthday format from 1/2/3456 to 34560102
sub frontPad($withWhat, $supposedStrLength, $strToPad) {
    my $theStrLength = $strToPad.chars;
    if $theStrLength >= $supposedStrLength { $strToPad; }
    else { $withWhat x ($supposedStrLength - $theStrLength) ~ $strToPad; }
}

class dateAct {
    method reformatDOB($aDOB) {
      $aDOB.Str.split(/\D/).map(frontPad("0", 2, $_)).rotate(-1).join;
    }
}

class insurFileAct is dateAct {
    method TOP($anInsurLine) {
      my $insurID = $anInsurLine<ptID>.Str;
      my $lastName = $anInsurLine<ptLastName>.Str;
      my $theDOB = $anInsurLine<ptDOB>.made; # this is not made;
      $anInsurLine.make("not yet made"); # not yet getting $theDOB to work
    }
    method ptDOB($DOB) { # ?ptDOB method is not called by named capture?
      my $newDOB = reformatDOB($DOB); # why is method not inherited
      $DOB.make($newDOB);
    }
}

my $insurAct = insurFileAct.new;
my $m = insurFile.parse($x, actions => $insurAct);

say $m.made;

И вывод:

===SORRY!=== Error while compiling /home/test.pl
Undeclared routine:
    reformatDOB used at line 41

person lisprogtor    schedule 06.02.2017    source источник


Ответы (3)


Вы пытаетесь вызвать несуществующую подпрограмму reformatDOB, а не метод.

В отличие, скажем, от Java, Perl6 не позволяет вам опустить invocant, т. е. вызов метода должен быть записан как

self.reformatDOB($DOB)

Кроме того, существуют также сокращенные формы, такие как

$.reformatDOB($DOB) # same as $(self.reformatDOB($DOB))
@.reformatDOB($DOB) # same as @(self.reformatDOB($DOB))
...

которые дополнительно накладывают контекст на возвращаемое значение.

person Christoph    schedule 06.02.2017
comment
Спасибо, Кристоф. Я знаю, что это должно быть что-то простое. Часто это очень маленькие вещи, которые трудно найти! Спасибо. - person lisprogtor; 07.02.2017

И еще: зачем изобретать велосипед? Есть Text::CSV для Perl 6:

https://github.com/Tux/CSV

установить либо:

panda install Text::CSV

or:

zef install Text::CSV
person Elizabeth Mattijsen    schedule 06.02.2017

Вы правы в том, что метод действия для имени именованного захвата не вызывается. Вместо этого он вызовет метод на основе имени совпадающей вещи. т.е. Поле будет вызвано.

Вы можете просто вызвать self.ptDOB($anInsurLine<ptDOB>) вручную из метода действия TOP.

person timotimo    schedule 07.02.2017
comment
Спасибо тимотимо! Вызов метода с совпадающим аргументом для создания моих собственных желаемых данных — это последняя часть головоломки, которая мне была нужна. Спасибо ! - person lisprogtor; 07.02.2017