Stackoverflow poster says Im looking for (how to make?) a function (module?) that gives nonzero integers between 1 and $input. Of course, in Perl, one can use the range operator to create such lists on the fly, as in 1 .. $input
and most answers are along those lines.
perldoc perlop says:
In the current implementation, no temporary array is created when the range operator is used as the expression in “foreach” loops, but older versions of Perl might burn a lot of memory when you write something like this:
for (1 .. 1_000_000) { # code }
Well, that’s excellent, but if you write my @x = (1 .. 1_000_000_000)
or my $x = [1 .. 1_000_000_000]
, you’re going to have problems.
So, I thought I would suggest lazily generating the sequence (parameter checking etc omitted):
sub make_lazy_increasing_sequence {
my ($current, $end) = map int, @_;
return sub {
return if $current > $end;
return $current++;
}
}
This returns an anonymous function which closes over the private instances of $current
and $end
. The line:
my $counter = make_lazy_increasing_sequence(1, 10);
creates a function that will generate integers between 1 and 10.
The line:
my $huge_counter = make_lazy_increasing_sequence(1, 10_000_000_000);
generates one that will yield a much longer sequence.
You can’t generate open ended sequences using the range operator. On the other hand, it is trivial to do so using closures:
my $neverending_increasing_sequence_from_5 = sub {
my ($x) = @_;
return sub { $x++ };
}->(5);
say $neverending_increasing_sequence_from_5->() for 1 .. 10;