You can return immediately if the string is less than or equal to the desired length. Then it depends on what you want to do to make it pretty. I have a couple of routines like this:
sub shorten_string {
my ( $string, $length ) = @_;
$length ||= 64;
$length = 10 if $length < 10;
return $string unless length($string) > $length;
my $chunk = int($length/2)-3;
return substr($string,0,$chunk+1) . ' ... ' . substr($string,-$chunk
+);
}
sub shorten_url {
my ( $url, $length ) = @_;
$length ||= 64;
return $url unless $url and length($url) > $length;
( $url ) = split /\?/, $url;
return $url if length($url) < $length or $url =~ m!\w+://[^/]+/?$!;
$url =~ s!(\w+://[^/]+)!!;
my $domain = $1 ? "$1/ ... " : '... ';
$length -= length $domain;
return $domain if $length < 1;
my @bits = split '/', $url;
my @keepers = $url =~ m!/$! ? ('') : ();
my $tail = 1;
while ( my $bit = pop @bits ) {
next unless $bit;
$length -= (length($bit) + 1);
unshift @keepers, $bit if $tail or $length > 0;
$tail = 0;
last if $length < 1;
}
return @keepers ? ( "$domain/".join'/',@keepers ) : $domain;
}