2017-02-06 4 views
3

Я пытаюсь разобрать файл csv, чтобы делать простые вещи: извлекать фамилию, ID и день рождения и изменять формат дня рождения с m/d/yyyy к yyyymmdd.perl6 Метод класса действия грамматики кажется не унаследованным, названный захват кажется не выполненным

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

(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 

Большое спасибо за вашу помощь !!!

ответ

5

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

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

self.reformatDOB($DOB) 

Кроме того, есть также сокращенные формы, как

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

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

+0

Спасибо, Кристоф. Я знаю, что это должно быть что-то простое. Часто это очень маленькие вещи, которые трудно найти! Благодарю. – lisprogtor

3

Также: зачем изобретать колесо? Там в Text :: CSV для Perl 6:

https://github.com/Tux/CSV

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

panda install Text::CSV 

или:

zef install Text::CSV 
+0

Спасибо, Элизабет Маттиссен! Я проверю этот пакет. – lisprogtor

1

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

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

+0

спасибо timotimo! Вызов метода с совпадающим аргументом для создания моих собственных желаемых данных - это последний фрагмент головоломки, в которой я нуждался. Благодаря ! – lisprogtor