Вот простое решение, которое использует карту и встроенный оператор дальности:
sub range {
my ($start, $end, $step) = @_;
$step ||= 1;
return map { $_ * $step } ($start / $step .. $end / $step);
}
Обратите внимание, что ключевым моментом здесь является блок карты {}. Мы просто делим конец
на данном шаге (работает для отрицательного и положительного), затем сопоставьте каждое значение
кратный данному шагу.