Abdullah Shaik Abdullah Shaik - 1 month ago 10
Perl Question

updated code for nric validation

I have updated my script to perform NRIC validation on the particular file. I put the open file outside the function. and perform the function in every line. The code work. I would like to clarify with you all whether is there any mistake.

my code below

#!/usr/bin/perl
use warnings;
open (my $fh, "<file.txt") or die "could not open file\n";
foreach (<$fh>)
{
print isValueNRIC(<$fh>);
}
sub isValueNRIC
{
my ($nric) = $_;
chomp $nric;

if ($nric !~ /^[STFG][0-9]{7}[A-Z]{1}$/)
{
return 0;
}
else
{
@values = split("",$nric);
chomp($values[8]);
$total = $values[1]*2+$values[2]*7+$values[3]*6+$values[4]*5+$values[5]*4+$values[6]*3+$values[7]*2;
if ($nric =~ /^[TG]/)
{
$total = $total +4;
}
$remainder = $total % 11;
if ($nric =~ /^[ST]/)
{
if ($remainder == 0 && $nric =~/J$/)
{
return 1;
}
elsif ($remainder == 1 && $nric =~/Z$/)
{
return 1;
}
elsif ($remainder == 2 && $nric =~/I$/)
{
return 1;
}
elsif ($remainder == 3 && $nric =~/H$/)
{
return 1;
}
elsif ($remainder == 4 && $nric =~/G$/)
{
return 1;
}
elsif ($remainder == 5 && $nric =~/F$/)
{
return 1;
}
elsif ($remainder == 6 && $nric =~/E$/)
{
return 1;
}
elsif ($remainder == 7 && $nric =~/D$/)
{
return 1;
}
elsif ($remainder == 8 && $nric =~/C$/)
{
return 1;
}
elsif ($remainder == 9 && $nric =~/B$/)
{
return 1;
}
elsif ($remainder == 10 && $nric =~/A$/)
{
return 1;
}
else
{
return 0;
}
}
else
{
if ($remainder == 0 && $nric =~/X$/)
{
return 1;
}
elsif ($remainder == 1 && $nric =~/W$/)
{
return 1;
}
elsif ($remainder == 2 && $nric =~/U$/)
{
return 1;
}
elsif ($remainder == 3 && $nric =~/T$/)
{
return 1;
}
elsif ($remainder == 4 && $nric =~/R$/)
{
return 1;
}
elsif ($remainder == 5 && $nric =~/Q$/)
{
return 1;
}
elsif ($remainder == 6 && $nric =~/P$/)
{
return 1;
}
elsif ($remainder == 7 && $nric =~/N$/)
{
return 1;
}
elsif ($remainder == 8 && $nric =~/M$/)
{
return 1;
}
elsif ($remainder == 9 && $nric =~/L$/)
{
return 1;
}
elsif ($remainder == 10 && $nric =~/K$/)
{
return 1;
}
else
{
return 0;
}
}
}
}


file.txt

S1111111F
S2222222A
S3333334B
S44444441
S1234567JA
S1234567D
S8258465Z
S8414469Z
S8266389D
S1677464B
S6697866D
S1682299Z
S1452132U
S9269800I
S2305966M
S2151631E
S7991159C
S9871515W
S8789136D
S8789136D
S1453616Q
S7047337B
S9571288Z
T9890759I
T1234567J


My question is that i want to pass the argument to the function(subroutine). Did I make any mistake. I do not understand on what the error states....

Answer Source

I'll just look at the first few lines...

You have been told at least twice to use both use warnings and use strict.

use warnings;

You have been told at least twice to use the three-arg version of open().

I also recommend including $! in the die() message, so you have a clue as to why the file open failed.

open (my $fh, "<file.txt") or die "could not open file\n";

You have been told at least twice to use while instead of foreach when reading from a file. And this is a great example of why you need to do that.

Using foreach reads all of the data from the file in one go. It's there, in a list waiting for Perl to hand it to you a line at a time each time you go round the loop. But after the first time you execute this statement, there is no more data waiting on this filehandle.

foreach (<$fh>)
{

Remember when I I said there was no more data waiting on this filehandle? That makes it a really stupid idea to ask for more data. There isn't any. You'll get undef back and you pass that undef into your subroutine and nothing in the subroutine will work as expected. What you wanted here was print isValueNRIC($_) as $_ contains the next line of data that has been read from $fh.

        print isValueNRIC(<$fh>);
}

Honestly, it looks like you're trying to write a program by trying random syntax and seeing what works. You don't seem to be reading (or, at least, understanding) any of the advice that you have received in answer to any of your previous questions.

I really recommend that you spend a week reading a good introductory Perl book (perhaps Learning Perl) and not trying to do any real work until you have learned at least the basics of Perl.