On Thu, Dec 02, 2004 at 04:33:49AM +0300, Alexey Tourbin wrote: > Тем более что зависимости 1: в общем-то harmful, т.к. Serial перекрывает > любую версию. Так что здесь тоже возможны казусы. Однако же v-strings > deprecated. Правда, будут какие-то version objects. > > Да, наверное три знака -- тоже неплохо (тогда для v-strings сохранится > один знак после точки, если отказаться от 1: зависимостей). Думаю остановиться на 3 цифрах и отказаться от Serial. Т.е. сейчас выполняются следующие тесты: cmp_ok "$d >= 2.0", 'eq', grok qq(use $m 2;); cmp_ok "$d >= 2.0", 'eq', grok qq(use $m 2.0;); cmp_ok "$d >= 2.0", 'eq', grok qq(use $m 2.00;); cmp_ok "$d >= 2.0", 'eq', grok qq(use $m 2.000998;); cmp_ok "$d >= 2.001", 'eq', grok qq(use $m 2.000999;); cmp_ok "$d >= 2.010", 'eq', grok qq(use $m 2.01;); cmp_ok "$d >= 2.012", 'eq', grok qq(use $m 2.012;); cmp_ok "$d >= 2.019", 'eq', grok qq(use $m 2.0199;); cmp_ok "$d >= 2.0", 'eq', grok qq(use $m v2;); cmp_ok "$d >= 2.0", 'eq', grok qq(use $m v2.0;); cmp_ok "$d >= 2.0", 'eq', grok qq(use $m v2.0.998;); cmp_ok "$d >= 2.001", 'eq', grok qq(use $m v2.0.999;); cmp_ok "$d >= 2.001", 'eq', grok qq(use $m 2.1.1;); cmp_ok "$d >= 2.001", 'eq', grok qq(use $m v2.1.1;); При этом для геренации версии отрабатывает следующий код: sub version ($) { my $sv = shift; my $class = class($sv); if ($class eq "IV" or $class eq "PVIV") { return verf($sv->int_value); } if ($class eq "NV" or $class eq "PVNV") { return verf($sv->NV); } if ($class eq "PVMG") { my @v; for (my $mg = $sv->MAGIC; $mg; $mg = $mg->MOREMAGIC) { next if $mg->TYPE ne "V"; @v = $mg->PTR =~ /(\d+)/g; last; } @v = map ord, split //, $sv->PV unless @v; return verf($v[0] + $v[1] / 1000 + $v[2] / 1000 / 1000); } return undef; } sub verf($) { my $v = shift; $v = sprintf("%.3f", int($v * 1000 + 1e-3) / 1000 + 1e-6); $v =~ s/\.000$/.0/g; return $v; } Подробности: sprintf "%.3f" может округлить в верхнюю сторону, а это не очень хорошо. Казалось бы, отрубить цифры после заданной -- нет проблем, однако же возникает казус: $ perl -le 'print 2.01 * 1000' 2010 $ perl -le 'print int(2.01 * 1000)' 2009 $ Поэтому в ход пошли 1e-3 и 1e-6.