Re: Passing user data to request callback

Gisle.Aas@nr.no
Tue, 28 Feb 95 15:04:52 +0100


m.koster@nexor.co.uk writes:
> > Perl 5.001 implements closures which should be able to handle this
> > better.  You should be able to say:
> 
> >     my $magic;
> >     $rc = request(..., sub { ...; something($magic)... }, ...);
> 
> Ehr... I'm not familiar with the term 'closure', can you elaborate?
> Are lexically scoped variables visible to subroutines defined in that
> scope?

Exactly.  Read this:

>From: lwall@netlabs.com (Larry Wall)
Subject: [comp.lang.perl] Re: What does the FSF have against Perl?
Date: 16 Feb 1995 12:46:32 +0100
Newsgroups: ifi.test.boa
Organization: NetLabs, Inc.
Original-Newsgroups: comp.lang.perl
Original-Date: Wed, 15 Feb 1995 20:06:24 GMT
X-filename: comp/lang/perl/42634

In article <D3sJBp.7sz@info.physics.utoronto.ca> elrick@helios.physics.utoronto.ca (Bruce Elrick) writes:
: In article <JNIALS.95Feb9134814@pentagon.io.com>,
: Jon R. Nials <jnials@pentagon.io.com> wrote:
: >In article <1995Feb7.170343.18714@netlabs.com>
: >lwall@netlabs.com (Larry Wall) writes:
: >
: >   Guess which language I added real closures to last night.  Hint: it's
: >   mostly just a text-processing language.  :-)
: >
: >Too cool.  Please tell me it is going to be in Patch001?  Please?
: >
: 
: Could someone explain the significance of this for my (and others', I
: might presume) edification?  I'm always willing to learn something new
: and this group is a perfect place for it.

This is a notion out of the Lisp world that says if you define an anonymous
function in a particular lexical context, it pretends to run in that
context even when it's called outside of the context.

In human terms, it's a funny way of passing arguments to a subroutine when
you define it as well as when you call it.  It's useful for setting up
little bits of code to run later, such as callbacks.  You can even
do object-oriented stuff with it, though Perl provides a different
mechanism to do that already.

You can also think of it as a way to write a subroutine template without
using eval.

Here's a small example of how this works:

    sub newprint {
	my $x = shift;
	return sub { my $y = shift; print "$x, $y!\n"; };
    }
    $h = newprint("Howdy");
    $g = newprint("Greetings");

    # Time passes...

    &$h("world");
    &$g("earthlings");

This prints (in my copy, not yours)

    Howdy, world!
    Greetings, earthlings!

Note particularly that $x continues to refer to the value passed into
newprint() *despite* the fact that the "my $x" has seemingly gone out of
scope by the time the anonymous subroutine runs.  That's what closure
is all about.

This only applies to lexical variables, by the way.  Dynamic variables
continue to work as they have always worked.  Closure is not something
that most Perl programmers need trouble themselves about to begin with.

Larry