closures and streams question

  • Thread starter grocery_stocker
  • Start date
G

grocery_stocker

The following code generates even numbers..

[cdalten@localhost oakland]$ more even.pl
#!/usr/bin/perl -w

sub even_number_printer_gen {
# This function returns a reference to an anon. subroutine.
# This anon. subroutine prints even numbers starting from $input.
my($input) = @_;
if ($input % 2) { $input++}; # Next even number, if the given
# number is odd
$rs = sub {
print "$input "; # Using $input,which is a my variable
# declared in an outside scope
$input += 2;
};
return $rs; # Return a reference to the subroutine above
}

my $iterator = even_number_printer_gen(30);
# $iterator now points to a closure.
# Every time you call it, it prints the next successive even number.
for ($i = 0; $i < 10; $i++) {
&$iterator();
}
print "\n";

[cdalten@localhost oakland]$ ./even.pl
30 32 34 36 38 40 42 44 46 48
[cdalten@localhost oakland]$

The thing I'm not seeing why using clousres would be important in this
case. Can someone enlighten me?
 
J

Jim Gibson

grocery_stocker said:
The following code generates even numbers..

[cdalten@localhost oakland]$ more even.pl
#!/usr/bin/perl -w

sub even_number_printer_gen {
# This function returns a reference to an anon. subroutine.
# This anon. subroutine prints even numbers starting from $input.
my($input) = @_;
if ($input % 2) { $input++}; # Next even number, if the given
# number is odd
$rs = sub {
print "$input "; # Using $input,which is a my variable
# declared in an outside scope
$input += 2;
};
return $rs; # Return a reference to the subroutine above
}

my $iterator = even_number_printer_gen(30);
# $iterator now points to a closure.
# Every time you call it, it prints the next successive even number.
for ($i = 0; $i < 10; $i++) {
&$iterator();
}
print "\n";

[cdalten@localhost oakland]$ ./even.pl
30 32 34 36 38 40 42 44 46 48
[cdalten@localhost oakland]$

The thing I'm not seeing why using clousres would be important in this
case. Can someone enlighten me?

One reason would be so you could define two such generators. Try:

my $iter1 = even_number_printer_gen(30);
my $iter2 = even_number_printer_gen(100);
for (my $i = 0; $i < 10; $i++) {
&$iter1();
$iter2->();
}
print "\n";

__OUTPUT__

30 100 32 102 34 104 36 106 38 108 40 110 42 112 44 114 46 116 48 118

Because the subroutine is defined as a closure, there are two values of
the lexical variable $input defined instead of a single, shared one.

Note the alternate method of calling the second generator function.
 
S

smallpond

The following code generates even numbers..

[cdalten@localhost oakland]$ more even.pl
#!/usr/bin/perl -w

sub even_number_printer_gen {
    # This function returns a reference to an anon. subroutine.
    # This anon. subroutine prints even numbers starting from $input.
    my($input) = @_;
    if ($input % 2) { $input++};  # Next even number, if the given
                                  # number is odd
    $rs = sub {
        print "$input ";  # Using $input,which is a my variable
                                  # declared in an outside scope
        $input  += 2;
    };
    return $rs;   # Return a reference to the subroutine above

}

my $iterator = even_number_printer_gen(30);
# $iterator now points to a closure.
# Every time you call it, it prints the next successive even number.
for ($i = 0; $i < 10; $i++) {
    &$iterator();}

print "\n";

[cdalten@localhost oakland]$ ./even.pl
30 32 34 36 38 40 42 44 46 48
[cdalten@localhost oakland]$

The thing I'm not seeing why using clousres would be important in this
case. Can someone enlighten me?


perl 5.10 has static "state" variables, you only need the closure in
5.8.

Why is it important? Can you be enlightened? Those aren't perl
questions. As an exercise, maybe try to access and print the value
of
$input inside your for loop.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,262
Messages
2,571,056
Members
48,769
Latest member
Clifft

Latest Threads

Top