Какую версию Вы предпочли бы?
#!/usr/bin/env perl
use warnings;
use strict;
use 5.010;
my $p = 7; # 33
my $prompt = ' : ';
my $key = 'very important text';
my $value = 'Hello, World!';
my $length = length $key . $prompt;
$p -= $length;
Опция 1:
$key = $key . ' ' x $p . $prompt;
Опция 2:
if ( $p > 0 ) {
$key = $key . ' ' x $p . $prompt;
}
else {
$key = $key . $prompt;
}
say "$key$value"
Мне не нравится вариант 2, поскольку он вводит ненужный особый случай.
Я бы реорганизовал конструкцию суффикса приглашения:
# Possible at top of program
my $suffix = ( ' ' x $p ) . $prompt;
# Later...
$key .= $suffix ;
Я бы предпочел
sprintf "%-7s : %s", $key, $value;
или
sprintf "%-*s : %s", $p, $key, $value;
вместо всей этой странной ерунды.
Из документации sprintf
:
Символы флага
'-'
Преобразованное значение должно корректироваться слева на границе поля. (По умолчанию это выравнивание по правому краю.) Преобразованное значение дополняется справа пробелами, а не слева пробелами или нулями.'-'
отменяет0
, если заданы оба значения.Ширина поля
Необязательная строка десятичных цифр (с ненулевой первой цифрой), определяющая минимальную ширину поля. Если преобразованное значение содержит меньше символов, чем ширина поля, оно будет дополнено пробелами слева (или справа, если установлен флаг регулировки влево). Вместо строки десятичных цифр можно написать
'*'
или'* m $'
(для некоторого десятичного целого числаm
), чтобы указать, что ширина поля равна задано в следующем аргументе или в m-м аргументе, соответственно, который должен иметь тип int. Отрицательная ширина поля принимается как флаг'-'
, за которым следует положительная ширина поля. Ни в коем случае несуществующее или малая ширина поля не приводит к усечению поля; если результат преобразования шире, чем ширина поля, поле расширяется, чтобы содержать результат преобразования.
Считайте меня старомодным, но я бы использовал printf() или sprintf():
printf "%-33s%s%s\n", $key, $prompt, $value;
Это слева оправдывает строку $key на 33 пробела, добавляет $prompt и $value и новую строку. Если бы я хотел динамически вычислить длину первой части:
printf "%-*s%s%s\n", $len, $key, $prompt, $value;
Поскольку это одна строка, а не 4 (вариант 1) или 6 (вариант 2), как в вопросе, это дает положительную оценку по шкале лаконичности.
Я выгляжу немного странно, но это работает (до сих пор):
#!/usr/bin/env perl
use warnings; use strict;
use 5.010;
use utf8;
use Term::Size;
my $columns = ( Term::Size::chars *STDOUT{IO} )[0];
binmode STDOUT, ':encoding(UTF-8)';
use Text::Wrap;
use Term::ANSIColor;
sub my_print {
my( $key, $value, $prompt, $color, $p ) = @_;
my $length = length $key.$prompt;
$p -= $length;
my $suff = ( ' ' x $p ) . $prompt;
$key .= $suff;
$length = length $key;
my $col = $columns - $length;
$Text::Wrap::columns = $col;
my @array = split /\n/, wrap ( '','', $value ) ;
$array[0] = colored( $key, $color ) . $array[0];
for my $idx ( 1..$#array ) {
$array[$idx] = ( ' ' x $length ) . $array[$idx];
}
say for @array;
}
my $prompt = ' : ';
my $color = 'magenta';
my $p = 30;
my $key = 'very important text';
my $value = 'text ' x 40;
my_print( $key, $value, $prompt, $color, $p );