closures and streams question

Discussion in 'Perl Misc' started by grocery_stocker, Feb 5, 2009.

  1. 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?
     
    grocery_stocker, Feb 5, 2009
    #1
    1. Advertising

  2. grocery_stocker

    Jim Gibson Guest

    In article
    <>,
    grocery_stocker <> wrote:

    > 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.

    --
    Jim Gibson
     
    Jim Gibson, Feb 5, 2009
    #2
    1. Advertising

  3. grocery_stocker

    smallpond Guest

    On Feb 5, 4:44 pm, grocery_stocker <> wrote:
    > 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.
     
    smallpond, Feb 5, 2009
    #3
  4. grocery_stocker <> wrote:

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



    The biggies are allowing multiple iterators and data encapsulation
    as in the other followups.

    See also:

    http://en.wikipedia.org/wiki/Closure_(computer_science)


    --
    Tad McClellan
    email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"
     
    Tad J McClellan, Feb 5, 2009
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Matthew Wilson
    Replies:
    6
    Views:
    301
    Bjoern Schliessmann
    Sep 27, 2007
  2. Fernando Perez

    Confused about closures and scoping rules

    Fernando Perez, Nov 7, 2007, in forum: Python
    Replies:
    2
    Views:
    331
    Fernando Perez
    Nov 7, 2007
  3. Aldric Giacomoni

    Closures / lambda question

    Aldric Giacomoni, Oct 28, 2009, in forum: Ruby
    Replies:
    12
    Views:
    195
    Waldemar Dick
    Oct 30, 2009
  4. Replies:
    2
    Views:
    172
    Richard Cornford
    Nov 13, 2005
  5. Alex K

    question about closures

    Alex K, Feb 10, 2011, in forum: Javascript
    Replies:
    14
    Views:
    233
    John G Harris
    Feb 12, 2011
Loading...

Share This Page