In the old unexplored code at work, I discovered a subroutine id2path that converts a numeric id of an object to a path (where some content related to the object is stored). I did not like the way how it was implemented, and adding strictures, underlines, and whitespace did not make it much better:
sub id2path { my $id = shift; return q() unless $id; my $path; if ($id > 999_999) { $path = sprintf '%03d/%03d/%03d', $id / 1_000_000, ($id / 1_000) % 1_000, $id % 1_000; } else { $path = sprintf '%02d/%02d/%02d', $id / 10_000, ($id / 100) % 100, $id % 100; } return $path; }
I do not like strange constants and repeated code. However, the only alternative I was able to write was the following:
sub id2path_new { my $id = shift or return q(); my $chunk_length = length $id > 6 ? 3 : 2; $id = sprintf '%0' . ($chunk_length * 3) . 'd', $id; my $chunk = ".{$chunk_length}"; my $path = join '/', $id =~ / ^ (.*) ($chunk) ($chunk) $ /xg; return $path; }
I do not like it much either. Do you have any ideas?
To make your work easier, here is how I tested it:
use Test::More tests => 23; is(id2path_new($_), id2path($_), "id=$_") for q(), 0, 1, 9, 10, 99, 100, 999, 1000, 9999, 10000, 99999, 100000, 999999, 1e6, 1e7-1, 1e7, 1e8-1, 1e8, 1e9, 1e10, 1e11, 1e12;
In reply to Can you make it nicer? by choroba
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |