Re: Perl 'grammar'
by ikegami (Patriarch) on Jan 08, 2008 at 22:58 UTC
|
You will rarely need C-style loops
for ($i = 0; $i <= $#sortedNames; $i++) {
If you need a counting loop, use the much more readable (and just as efficient)
for my $i (0..$#sortedNames) {
Or when iterating over a list or array, you can use
for my $name (@sortedNames) {
Why use reverse to prepend a string?
$toOutput = reverse $temp[0];
$toOutput .= $x;
$output = reverse $toOutput;
is the same as
$output = $x . $temp[0];
| [reply] [d/l] [select] |
|
|
Thank you for your insight. I've been away from Perl for too long. Far too long.
| [reply] |
Re: Perl 'grammar'
by toolic (Bishop) on Jan 08, 2008 at 21:02 UTC
|
I would tend to use substr rather than reverse to abbreviate the first name in this case:
#!/usr/bin/env perl
use warnings;
use strict;
while (<DATA>) {
my ($last, $first) = split /,/;
$last =~ s/\s+//;
$first =~ s/\s+//;
print substr($first, 0, 1), $last, "\n";
}
__DATA__
Smith, John
Bar, Foo
Prints out:
JSmith
FBar
| [reply] [d/l] [select] |
|
|
Why not let the split regex do some of the work of removing spaces?
my ( $last, $first ) = split m{\s*,\s*};
Cheers, JohnGG | [reply] [d/l] [select] |
Re: Perl 'grammar'
by gamache (Friar) on Jan 08, 2008 at 21:10 UTC
|
Here is a Perlish way to convert a name into AD format:
sub format_name_for_AD {
my $empl_name = shift; # $empl_name has the form "Last,
+ First"
my ($last, $first) = $empl_name=~/^([^,]+), (.+)/ or return undef;
return uc(substr($first, 0, 1)) . ucfirst($last);
}
for ('Smith, John', 'Wall, Larry', 'Perlis, Alan', 'Ritchie, Dennis')
+{
print format_name_for_AD($_), "\n";
}
I'll leave what's going on as an exercise to the reader (hint: perlre), but as a short comment, I'll say that string matching in Perl shouldn't look like string matching in C. :) | [reply] [d/l] |
|
|
my $empl_name = shift;
my ($last, $first) = $empl_name=~/^([^,]+), (.+)/ or return undef;
preferred over
my ($last, $first) = /(.*), (.*)/ or return undef;
(or perhaps /(.*),\s*(.*)/ ?) | [reply] [d/l] [select] |
|
|
Hell, why not sub format_name_for_AD {/(.+), (.)/ ? $2.$1 : undef}?
| [reply] [d/l] |
|
|
|
|
|
|
|
The two are not the same. Consider what happens when the sub is called as format_name_for_AD($foo).
| [reply] [d/l] |
|
|
Re: Perl 'grammar'
by dragonchild (Archbishop) on Jan 08, 2008 at 22:16 UTC
|
In C, you have to work with each item in itself. With Perl, you work with the whole thing at once. So, you have an idea of what you're starting and where you want to go.
# Starting with Lastname, Firstname
# Wanting to get to FLastname
sub transform {
my ($name) = @_;
$name =~ s/^\s*(\S+),\s(\S)/${2}${1}/;
return $name;
}
So, grab what you want from what you're given, transform it into what you want, then return it. It's often best to do this sort of thing in a function because it's easier to be destructive and smaller scopes give you greater flexibility. You don't have to watch out for anyone else's feelings. :-)
My criteria for good software:
- Does it work?
- Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
| [reply] [d/l] |
|
|
Not quite.. :-)
That returns JSmithohn
sub transform {
my ($name) = @_;
$name =~ s/^\s*(\S+),\s(\S)\S+$/${2}${1}/;
# Added '\S+$'
return $name;
}
| [reply] [d/l] |
|
|
Nice catch. A better version of the regex would be s/^\s*(\S+),\s+(\S).*$/${2}${1}/; - you don't want to assume too much about the item. That's why the ^\s*(\S+) instead of just ^(\S+).
My criteria for good software:
- Does it work?
- Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
| [reply] [d/l] [select] |
|
|
|
|
|
Re: Perl 'grammar'
by jdporter (Paladin) on Jan 09, 2008 at 02:44 UTC
|
use strict;
my @fullnames = (
"Smith, David",
"Lamb, Mary",
"Depp, Johnny",
"Child, Julia",
);
my %x = map { /(.*), (.)/ ? ( $_ => $2.$1 ) : () } @fullnames;
print "$_ => $x{$_}\n" for keys %x;
Oh, I'm sorry — you said
if Perl wasn't my [0]th language.
;-)
A word spoken in Mind will reach its own level, in the objective world, by its own wei ght
| [reply] [d/l] [select] |
Re: Perl 'grammar'
by memnoch (Scribe) on Jan 08, 2008 at 21:11 UTC
|
The following assumes that the input names are formatted correctly. (If not you might want to look at the lc and ucfirst functions.)
use strict;
my @fullnames = ("Smith, David", "Lamb, Mary", "Depp, Johnny", "Child,
+ Julia");
foreach my $fullname (@fullnames) {
my ($last, $first) = map {s/^\s*//; $_} split /,/, $fullname;
$first =~ s/^(\w).*/$1/;
my $id = $first . $last;
print "\$id = $id\n";
}
| [reply] [d/l] |
| A reply falls below the community's threshold of quality. You may see it by logging in. |