[Omaha.pm] sprintf is your friend
Jay Hannah
jay at jays.net
Mon Aug 28 18:11:18 PDT 2006
Daniel Linder wrote:
> On Fri, August 25, 2006 15:47, Jay Hannah wrote:
>> Before:
>>
>> sub prepend_pegheader
>> {
>> my ($str, $msgtype) = (@_);
>> my $len = length($str) + 6;
>> $len = "00000" . $len; # Just slap 5 zeroes onto the front and
>> only
>> $len =~ s/^\d+(\d{5})$/$1/; # take the last 5 characters.
>> $str = "$msgtype$len$str";
>> return $str;
>> }
>
> I don't like this -- it seems to use a lot of extra steps to achieve the
> same result. I'd only use this over the other one if it was faster and
> that was a paramount issue in the program.
Indeed. Whenever I post "Before:" and "After:" code samples I'm asserting that the "After:" is a better way to do the same thing. It appears you and I agree in this case. :)
> The only place I can realistically see this breaking is if "len" is >99999
> - thus only the last five digits of the real number would get captured.
> At least with "sprintf" it will expand the "%05d" to show all six digits
> if needed. Of course that might be the intent so that the sixth column is
> *always* the start of "str" nomatter what.
>
> dan at dglinder:~/tmp$ cat d.pl
> #!perl -w
>
> $number = 123;
> $line = sprintf ("1: %05d\n", $number);
> printf ("%s", $line);
>
> $number = 123123;
> $line = sprintf ("2: %05d\n", $number);
> printf ("%s", $line);
>
> dan at dglinder:~/tmp$ perl ./d.pl
> 1: 00123
> 2: 123123
Ah, yes. Good point about numbers > 99999. In my particular context, such a thing is not supposed to be possible so I think my conversion was valid.
>> After:
>> sub prepend_pegheader
>> {
>> my ($str, $msgtype) = (@_);
>> my $len = sprintf("%05d", length($str) + 6);
>> return "$msgtype$len$str";
>> }
>
> This is my pick, even if it is a slight bit slower in the end -- much more
> readable. If you do get six digits showing up where you only wanted five
> then I would recommend that you check why the length of "str" is so great,
> and either adjust the five digits to six or larger, or fix the input being
> placed into "str".
In my particular context the vendor specification does not allow for lengths > 99999. So I don't know what I "should do" if the length was longer. Dump core and page everyone, probably. :)
After I posted that I was have tempted to Perl golf it down to
sub prepend_pegheader {
my ($str, $msgtype) = (@_);
return sprintf("%s%05d%s", $msgtype, length($str) + 6, $str);
}
or
sub prepend_pegheader {
sprintf("%s%05d%s", $_[1], length($_[0]) + 6, $_[0]);
}
or no sub at all since it's one line now. :)
But I'm not that evil. I like being able to read the code I wrote yesterday without excessive quantities of ellicit drugs.
j
More information about the Omaha-pm
mailing list