Confused about closures

K

Krishna Chaitanya

Hi,

Following's an extract from Perl FAQ 7.13 (closures):

****************
Closures are often used for less esoteric purposes. For example,
when
you want to pass in a bit of code into a function:
my $line;
timeout( 30, sub { $line = <STDIN> } );
If the code to execute had been passed in as a string, '$line =
<STDIN>', there would have been no way for the hypothetical
timeout()
function to access the lexical variable $line back in its
caller's
scope.
****************

I'm not clear about what's being said here...why would timeout need to
access $line here at all? What would be wrong with:

timeout(30,scalar(<STDIN>));

What's the real, "less esoteric", use of the closure being described
here? Pls. help me...am I missing something obvious?

Thanks in advance,
Chaitanya

P.S: Pardon me if this is something silly which's escaping me...am
overworked. Pls. bear...
 
J

jl_post

Following's an extract from Perl FAQ 7.13 (closures):

****************
    Closures are often used for less esoteric purposes. For example,
when
    you want to pass in a bit of code into a function:
            my $line;
            timeout( 30, sub { $line = <STDIN> } );
    If the code to execute had been passed in as a string, '$line =
    <STDIN>', there would have been no way for the hypothetical
timeout()
    function to access the lexical variable $line back in its
caller's
    scope.
****************

I'm not clear about what's being said here...why would timeout
need to access $line here at all?


I think what perlfaq7 is trying to say is that timeout() is just a
hypothetical function that someone might need to create: nothing more
than a function that takes a subroutine as an argument.

Instead of passing in sub { ... } as an argument to a function,
sometimes people will pass in a string containing code, to be eval()ed
in the function.

What would be wrong with:

timeout(30,scalar(<STDIN>));


If you did that, then $line wouldn't be populated. Apparently the
person who created the hypothetical timeout() function wants to
populate $line with input taken from STDIN. Your way
( timeout(30,scalar(<STDIN>)) ) wouldn't do that. Not only that, but
your way would execute scalar(<STDIN>) right before the timeout()
function was called, instead of inside it.

What's the real, "less esoteric", use of the closure being described
here? Pls. help me...am I missing something obvious?


I think perlfaq7 means it's "less esoteric" when compared to
passing in the code as a string, like this:

timeout( 30, '$line = <STDIN>' );

If a programmer wants to pass in code to execute inside a function
(during the function's execution), sometimes they will pass the code
into the function as a string, and then eval() it in the function.

However, the "less esoteric" way of doing it is to pass it in as a
subroutine reference itself -- that is, instead of passing in '$line =
<STDIN>', you pass in sub { $line = <STDIN> }. That way the $line
variable can refer to the one that was declared (with "my") right
before the call to timeout().

In other words, when executing the passed-in code with:

my $line;
timeout( 30, sub { $line = <STDIN> } );

the $line variable we see here gets populated. But with:

my $line;
timeout( 30, '$line = <STDIN>' );

then the $line variable we see here WON'T get populated. Instead, a
$line variable visible in the timeout() function will get populated
instead (when the code gets eval()ed in the timeout() function).

So if you want the $line variable (the one we're seeing declared
before the call to timeout()) to be populated, using the closure is
the better way to do it.

I hope that helps, Chaitanya.

Cheers,

-- Jean-Luc
 
X

Xho Jingleheimerschmidt

Krishna said:
Hi,

Following's an extract from Perl FAQ 7.13 (closures):

****************
Closures are often used for less esoteric purposes. For example,
when
you want to pass in a bit of code into a function:
my $line;
timeout( 30, sub { $line = <STDIN> } );
If the code to execute had been passed in as a string, '$line =
<STDIN>', there would have been no way for the hypothetical
timeout()
function to access the lexical variable $line back in its
caller's
scope.
****************

I'm not clear about what's being said here...why would timeout need to
access $line here at all? What would be wrong with:

timeout(30,scalar(<STDIN>));

Two things. First of all, that would wait (potentially forever) for a
line to be read from STDIN, *before* timeout got executed. This would
presumably defeat the purpose of having a subroutine named timeout. But
this has nothing to do with closures.

Second, if you want the next line in STDIN to be thrown away, that would
be fine. But presumably you want it to be assigned to $line, otherwise
you wouldn't be assigning it to $line.

Xho
 

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
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top