I am trying to parse a csv file to do simple things: extract last name, ID, and birthday, and change format of birthday from m/d/yyyy to yyyymmdd.
(1) I used named capture for birthdays, but it seems that named captures method are not called to make what I want.
(2) Inheriting grammar action methods seems not working for named captures.
What did I do wrong?
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;
And the output is:
===SORRY!=== Error while compiling /home/test.pl
Undeclared routine:
reformatDOB used at line 41
You're trying to invoke the non-existing subroutine reformatDOB
, not a method.
In contrast to, say, Java, Perl6 does not allow you to omit the invocant, ie the method call has to be written as
self.reformatDOB($DOB)
In addition, there are also shorthand forms like
$.reformatDOB($DOB) # same as $(self.reformatDOB($DOB))
@.reformatDOB($DOB) # same as @(self.reformatDOB($DOB))
...
that additionally impose context on the return value.
Also: why reinvent the wheel? There's Text::CSV for Perl 6:
https://github.com/Tux/CSV
install with either:
panda install Text::CSV
or:
zef install Text::CSV
You are right in that the action method for the name of the named capture doesn't get called. Instead, it will call the method based on the name of the thing that was matched. I.e. aField will be called.
You can just call self.ptDOB($anInsurLine<ptDOB>)
manually from your TOP action method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With