[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Omaha.pm] sprintf is your friend



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@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@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